0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/clk.h>
0010 #include <linux/delay.h>
0011 #include <linux/gpio/consumer.h>
0012 #include <linux/init.h>
0013 #include <linux/module.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/pinctrl/consumer.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/pm.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/irq.h>
0020 #include <linux/suspend.h>
0021 #include <linux/time.h>
0022 #include <linux/greybus.h>
0023 #include "arche_platform.h"
0024
0025 #if IS_ENABLED(CONFIG_USB_HSIC_USB3613)
0026 #include <linux/usb/usb3613.h>
0027 #else
0028 static inline int usb3613_hub_mode_ctrl(bool unused)
0029 {
0030 return 0;
0031 }
0032 #endif
0033
0034 #define WD_COLDBOOT_PULSE_WIDTH_MS 30
0035
0036 enum svc_wakedetect_state {
0037 WD_STATE_IDLE,
0038 WD_STATE_BOOT_INIT,
0039 WD_STATE_COLDBOOT_TRIG,
0040 WD_STATE_STANDBYBOOT_TRIG,
0041 WD_STATE_COLDBOOT_START,
0042 WD_STATE_STANDBYBOOT_START,
0043 };
0044
0045 struct arche_platform_drvdata {
0046
0047 struct gpio_desc *svc_reset;
0048 bool is_reset_act_hi;
0049 struct gpio_desc *svc_sysboot;
0050 struct gpio_desc *wake_detect;
0051
0052 enum arche_platform_state state;
0053
0054 struct gpio_desc *svc_refclk_req;
0055 struct clk *svc_ref_clk;
0056
0057 struct pinctrl *pinctrl;
0058 struct pinctrl_state *pin_default;
0059
0060 int num_apbs;
0061
0062 enum svc_wakedetect_state wake_detect_state;
0063 int wake_detect_irq;
0064 spinlock_t wake_lock;
0065 struct mutex platform_state_mutex;
0066 unsigned long wake_detect_start;
0067 struct notifier_block pm_notifier;
0068
0069 struct device *dev;
0070 };
0071
0072
0073 static void arche_platform_set_state(struct arche_platform_drvdata *arche_pdata,
0074 enum arche_platform_state state)
0075 {
0076 arche_pdata->state = state;
0077 }
0078
0079
0080 static void arche_platform_set_wake_detect_state(struct arche_platform_drvdata *arche_pdata,
0081 enum svc_wakedetect_state state)
0082 {
0083 arche_pdata->wake_detect_state = state;
0084 }
0085
0086 static inline void svc_reset_onoff(struct gpio_desc *gpio, bool onoff)
0087 {
0088 gpiod_set_raw_value(gpio, onoff);
0089 }
0090
0091 static int apb_cold_boot(struct device *dev, void *data)
0092 {
0093 int ret;
0094
0095 ret = apb_ctrl_coldboot(dev);
0096 if (ret)
0097 dev_warn(dev, "failed to coldboot\n");
0098
0099
0100 return 0;
0101 }
0102
0103 static int apb_poweroff(struct device *dev, void *data)
0104 {
0105 apb_ctrl_poweroff(dev);
0106
0107
0108 if (usb3613_hub_mode_ctrl(false))
0109 dev_warn(dev, "failed to control hub device\n");
0110
0111 return 0;
0112 }
0113
0114 static void arche_platform_wd_irq_en(struct arche_platform_drvdata *arche_pdata)
0115 {
0116
0117 enable_irq(arche_pdata->wake_detect_irq);
0118 }
0119
0120 static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid)
0121 {
0122 struct arche_platform_drvdata *arche_pdata = devid;
0123 unsigned long flags;
0124
0125 spin_lock_irqsave(&arche_pdata->wake_lock, flags);
0126 if (arche_pdata->wake_detect_state != WD_STATE_COLDBOOT_TRIG) {
0127
0128 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
0129 return IRQ_HANDLED;
0130 }
0131
0132 arche_platform_set_wake_detect_state(arche_pdata,
0133 WD_STATE_COLDBOOT_START);
0134 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
0135
0136
0137 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
0138
0139
0140 device_for_each_child(arche_pdata->dev, NULL, apb_cold_boot);
0141
0142
0143 if (usb3613_hub_mode_ctrl(true))
0144 dev_warn(arche_pdata->dev, "failed to control hub device\n");
0145
0146 spin_lock_irqsave(&arche_pdata->wake_lock, flags);
0147 arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);
0148 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
0149
0150 return IRQ_HANDLED;
0151 }
0152
0153 static irqreturn_t arche_platform_wd_irq(int irq, void *devid)
0154 {
0155 struct arche_platform_drvdata *arche_pdata = devid;
0156 unsigned long flags;
0157
0158 spin_lock_irqsave(&arche_pdata->wake_lock, flags);
0159
0160 if (gpiod_get_value(arche_pdata->wake_detect)) {
0161
0162
0163
0164
0165
0166
0167
0168 if (arche_pdata->wake_detect_state == WD_STATE_BOOT_INIT) {
0169 if (time_before(jiffies,
0170 arche_pdata->wake_detect_start +
0171 msecs_to_jiffies(WD_COLDBOOT_PULSE_WIDTH_MS))) {
0172 arche_platform_set_wake_detect_state(arche_pdata,
0173 WD_STATE_IDLE);
0174 } else {
0175
0176
0177
0178
0179 if (arche_pdata->wake_detect_state !=
0180 WD_STATE_COLDBOOT_START) {
0181 arche_platform_set_wake_detect_state(arche_pdata,
0182 WD_STATE_COLDBOOT_TRIG);
0183 spin_unlock_irqrestore(&arche_pdata->wake_lock,
0184 flags);
0185 return IRQ_WAKE_THREAD;
0186 }
0187 }
0188 }
0189 } else {
0190
0191 if (arche_pdata->wake_detect_state == WD_STATE_IDLE) {
0192 arche_pdata->wake_detect_start = jiffies;
0193
0194
0195
0196
0197
0198
0199
0200 arche_platform_set_wake_detect_state(arche_pdata,
0201 WD_STATE_BOOT_INIT);
0202 }
0203 }
0204
0205 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
0206
0207 return IRQ_HANDLED;
0208 }
0209
0210
0211
0212
0213 static int
0214 arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata)
0215 {
0216 int ret;
0217
0218 if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE)
0219 return 0;
0220
0221 dev_info(arche_pdata->dev, "Booting from cold boot state\n");
0222
0223 svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi);
0224
0225 gpiod_set_value(arche_pdata->svc_sysboot, 0);
0226 usleep_range(100, 200);
0227
0228 ret = clk_prepare_enable(arche_pdata->svc_ref_clk);
0229 if (ret) {
0230 dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n",
0231 ret);
0232 return ret;
0233 }
0234
0235
0236 svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi);
0237
0238 arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_ACTIVE);
0239
0240 return 0;
0241 }
0242
0243
0244
0245
0246 static int
0247 arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata)
0248 {
0249 int ret;
0250
0251 if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
0252 return 0;
0253
0254 dev_info(arche_pdata->dev, "Switching to FW flashing state\n");
0255
0256 svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi);
0257
0258 gpiod_set_value(arche_pdata->svc_sysboot, 1);
0259
0260 usleep_range(100, 200);
0261
0262 ret = clk_prepare_enable(arche_pdata->svc_ref_clk);
0263 if (ret) {
0264 dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n",
0265 ret);
0266 return ret;
0267 }
0268
0269 svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi);
0270
0271 arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_FW_FLASHING);
0272
0273 return 0;
0274 }
0275
0276
0277
0278
0279 static void
0280 arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata)
0281 {
0282 unsigned long flags;
0283
0284 if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF)
0285 return;
0286
0287
0288 if (arche_pdata->state != ARCHE_PLATFORM_STATE_FW_FLASHING) {
0289 disable_irq(arche_pdata->wake_detect_irq);
0290
0291 spin_lock_irqsave(&arche_pdata->wake_lock, flags);
0292 arche_platform_set_wake_detect_state(arche_pdata,
0293 WD_STATE_IDLE);
0294 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
0295 }
0296
0297 clk_disable_unprepare(arche_pdata->svc_ref_clk);
0298
0299
0300 svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi);
0301
0302 arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);
0303 }
0304
0305 static ssize_t state_store(struct device *dev,
0306 struct device_attribute *attr,
0307 const char *buf, size_t count)
0308 {
0309 struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev);
0310 int ret = 0;
0311
0312 mutex_lock(&arche_pdata->platform_state_mutex);
0313
0314 if (sysfs_streq(buf, "off")) {
0315 if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF)
0316 goto exit;
0317
0318
0319 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
0320
0321 arche_platform_poweroff_seq(arche_pdata);
0322
0323 } else if (sysfs_streq(buf, "active")) {
0324 if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE)
0325 goto exit;
0326
0327
0328
0329
0330 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
0331 arche_platform_poweroff_seq(arche_pdata);
0332
0333 arche_platform_wd_irq_en(arche_pdata);
0334 ret = arche_platform_coldboot_seq(arche_pdata);
0335 if (ret)
0336 goto exit;
0337
0338 } else if (sysfs_streq(buf, "standby")) {
0339 if (arche_pdata->state == ARCHE_PLATFORM_STATE_STANDBY)
0340 goto exit;
0341
0342 dev_warn(arche_pdata->dev, "standby state not supported\n");
0343 } else if (sysfs_streq(buf, "fw_flashing")) {
0344 if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
0345 goto exit;
0346
0347
0348
0349
0350
0351
0352
0353
0354 arche_platform_poweroff_seq(arche_pdata);
0355
0356 ret = arche_platform_fw_flashing_seq(arche_pdata);
0357 if (ret)
0358 goto exit;
0359 } else {
0360 dev_err(arche_pdata->dev, "unknown state\n");
0361 ret = -EINVAL;
0362 }
0363
0364 exit:
0365 mutex_unlock(&arche_pdata->platform_state_mutex);
0366 return ret ? ret : count;
0367 }
0368
0369 static ssize_t state_show(struct device *dev,
0370 struct device_attribute *attr, char *buf)
0371 {
0372 struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev);
0373
0374 switch (arche_pdata->state) {
0375 case ARCHE_PLATFORM_STATE_OFF:
0376 return sprintf(buf, "off\n");
0377 case ARCHE_PLATFORM_STATE_ACTIVE:
0378 return sprintf(buf, "active\n");
0379 case ARCHE_PLATFORM_STATE_STANDBY:
0380 return sprintf(buf, "standby\n");
0381 case ARCHE_PLATFORM_STATE_FW_FLASHING:
0382 return sprintf(buf, "fw_flashing\n");
0383 default:
0384 return sprintf(buf, "unknown state\n");
0385 }
0386 }
0387
0388 static DEVICE_ATTR_RW(state);
0389
0390 static int arche_platform_pm_notifier(struct notifier_block *notifier,
0391 unsigned long pm_event, void *unused)
0392 {
0393 struct arche_platform_drvdata *arche_pdata =
0394 container_of(notifier, struct arche_platform_drvdata,
0395 pm_notifier);
0396 int ret = NOTIFY_DONE;
0397
0398 mutex_lock(&arche_pdata->platform_state_mutex);
0399 switch (pm_event) {
0400 case PM_SUSPEND_PREPARE:
0401 if (arche_pdata->state != ARCHE_PLATFORM_STATE_ACTIVE) {
0402 ret = NOTIFY_STOP;
0403 break;
0404 }
0405 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
0406 arche_platform_poweroff_seq(arche_pdata);
0407 break;
0408 case PM_POST_SUSPEND:
0409 if (arche_pdata->state != ARCHE_PLATFORM_STATE_OFF)
0410 break;
0411
0412 arche_platform_wd_irq_en(arche_pdata);
0413 arche_platform_coldboot_seq(arche_pdata);
0414 break;
0415 default:
0416 break;
0417 }
0418 mutex_unlock(&arche_pdata->platform_state_mutex);
0419
0420 return ret;
0421 }
0422
0423 static int arche_platform_probe(struct platform_device *pdev)
0424 {
0425 struct arche_platform_drvdata *arche_pdata;
0426 struct device *dev = &pdev->dev;
0427 struct device_node *np = dev->of_node;
0428 int ret;
0429 unsigned int flags;
0430
0431 arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata),
0432 GFP_KERNEL);
0433 if (!arche_pdata)
0434 return -ENOMEM;
0435
0436
0437 arche_pdata->is_reset_act_hi = of_property_read_bool(np,
0438 "svc,reset-active-high");
0439 if (arche_pdata->is_reset_act_hi)
0440 flags = GPIOD_OUT_HIGH;
0441 else
0442 flags = GPIOD_OUT_LOW;
0443
0444 arche_pdata->svc_reset = devm_gpiod_get(dev, "svc,reset", flags);
0445 if (IS_ERR(arche_pdata->svc_reset)) {
0446 ret = PTR_ERR(arche_pdata->svc_reset);
0447 dev_err(dev, "failed to request svc-reset GPIO: %d\n", ret);
0448 return ret;
0449 }
0450 arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);
0451
0452 arche_pdata->svc_sysboot = devm_gpiod_get(dev, "svc,sysboot",
0453 GPIOD_OUT_LOW);
0454 if (IS_ERR(arche_pdata->svc_sysboot)) {
0455 ret = PTR_ERR(arche_pdata->svc_sysboot);
0456 dev_err(dev, "failed to request sysboot0 GPIO: %d\n", ret);
0457 return ret;
0458 }
0459
0460
0461 arche_pdata->svc_refclk_req = devm_gpiod_get(dev, "svc,refclk-req",
0462 GPIOD_IN);
0463 if (IS_ERR(arche_pdata->svc_refclk_req)) {
0464 ret = PTR_ERR(arche_pdata->svc_refclk_req);
0465 dev_err(dev, "failed to request svc-clk-req GPIO: %d\n", ret);
0466 return ret;
0467 }
0468
0469
0470 arche_pdata->svc_ref_clk = devm_clk_get(dev, "svc_ref_clk");
0471 if (IS_ERR(arche_pdata->svc_ref_clk)) {
0472 ret = PTR_ERR(arche_pdata->svc_ref_clk);
0473 dev_err(dev, "failed to get svc_ref_clk: %d\n", ret);
0474 return ret;
0475 }
0476
0477 platform_set_drvdata(pdev, arche_pdata);
0478
0479 arche_pdata->num_apbs = of_get_child_count(np);
0480 dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs);
0481
0482 arche_pdata->wake_detect = devm_gpiod_get(dev, "svc,wake-detect",
0483 GPIOD_IN);
0484 if (IS_ERR(arche_pdata->wake_detect)) {
0485 ret = PTR_ERR(arche_pdata->wake_detect);
0486 dev_err(dev, "Failed requesting wake_detect GPIO: %d\n", ret);
0487 return ret;
0488 }
0489
0490 arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);
0491
0492 arche_pdata->dev = &pdev->dev;
0493
0494 spin_lock_init(&arche_pdata->wake_lock);
0495 mutex_init(&arche_pdata->platform_state_mutex);
0496 arche_pdata->wake_detect_irq =
0497 gpiod_to_irq(arche_pdata->wake_detect);
0498
0499 ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq,
0500 arche_platform_wd_irq,
0501 arche_platform_wd_irq_thread,
0502 IRQF_TRIGGER_FALLING |
0503 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
0504 dev_name(dev), arche_pdata);
0505 if (ret) {
0506 dev_err(dev, "failed to request wake detect IRQ %d\n", ret);
0507 return ret;
0508 }
0509 disable_irq(arche_pdata->wake_detect_irq);
0510
0511 ret = device_create_file(dev, &dev_attr_state);
0512 if (ret) {
0513 dev_err(dev, "failed to create state file in sysfs\n");
0514 return ret;
0515 }
0516
0517 ret = of_platform_populate(np, NULL, NULL, dev);
0518 if (ret) {
0519 dev_err(dev, "failed to populate child nodes %d\n", ret);
0520 goto err_device_remove;
0521 }
0522
0523 arche_pdata->pm_notifier.notifier_call = arche_platform_pm_notifier;
0524 ret = register_pm_notifier(&arche_pdata->pm_notifier);
0525
0526 if (ret) {
0527 dev_err(dev, "failed to register pm notifier %d\n", ret);
0528 goto err_device_remove;
0529 }
0530
0531
0532 if (!of_property_read_bool(pdev->dev.of_node, "arche,init-off")) {
0533 mutex_lock(&arche_pdata->platform_state_mutex);
0534 ret = arche_platform_coldboot_seq(arche_pdata);
0535 if (ret) {
0536 dev_err(dev, "Failed to cold boot svc %d\n", ret);
0537 goto err_coldboot;
0538 }
0539 arche_platform_wd_irq_en(arche_pdata);
0540 mutex_unlock(&arche_pdata->platform_state_mutex);
0541 }
0542
0543 dev_info(dev, "Device registered successfully\n");
0544 return 0;
0545
0546 err_coldboot:
0547 mutex_unlock(&arche_pdata->platform_state_mutex);
0548 err_device_remove:
0549 device_remove_file(&pdev->dev, &dev_attr_state);
0550 return ret;
0551 }
0552
0553 static int arche_remove_child(struct device *dev, void *unused)
0554 {
0555 struct platform_device *pdev = to_platform_device(dev);
0556
0557 platform_device_unregister(pdev);
0558
0559 return 0;
0560 }
0561
0562 static int arche_platform_remove(struct platform_device *pdev)
0563 {
0564 struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev);
0565
0566 unregister_pm_notifier(&arche_pdata->pm_notifier);
0567 device_remove_file(&pdev->dev, &dev_attr_state);
0568 device_for_each_child(&pdev->dev, NULL, arche_remove_child);
0569 arche_platform_poweroff_seq(arche_pdata);
0570
0571 if (usb3613_hub_mode_ctrl(false))
0572 dev_warn(arche_pdata->dev, "failed to control hub device\n");
0573
0574 return 0;
0575 }
0576
0577 static __maybe_unused int arche_platform_suspend(struct device *dev)
0578 {
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588 return 0;
0589 }
0590
0591 static __maybe_unused int arche_platform_resume(struct device *dev)
0592 {
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602 return 0;
0603 }
0604
0605 static void arche_platform_shutdown(struct platform_device *pdev)
0606 {
0607 struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev);
0608
0609 arche_platform_poweroff_seq(arche_pdata);
0610
0611 usb3613_hub_mode_ctrl(false);
0612 }
0613
0614 static SIMPLE_DEV_PM_OPS(arche_platform_pm_ops,
0615 arche_platform_suspend,
0616 arche_platform_resume);
0617
0618 static const struct of_device_id arche_platform_of_match[] = {
0619
0620 { .compatible = "google,arche-platform", },
0621 { },
0622 };
0623
0624 static const struct of_device_id arche_combined_id[] = {
0625
0626 { .compatible = "google,arche-platform", },
0627 { .compatible = "usbffff,2", },
0628 { },
0629 };
0630 MODULE_DEVICE_TABLE(of, arche_combined_id);
0631
0632 static struct platform_driver arche_platform_device_driver = {
0633 .probe = arche_platform_probe,
0634 .remove = arche_platform_remove,
0635 .shutdown = arche_platform_shutdown,
0636 .driver = {
0637 .name = "arche-platform-ctrl",
0638 .pm = &arche_platform_pm_ops,
0639 .of_match_table = arche_platform_of_match,
0640 }
0641 };
0642
0643 static int __init arche_init(void)
0644 {
0645 int retval;
0646
0647 retval = platform_driver_register(&arche_platform_device_driver);
0648 if (retval)
0649 return retval;
0650
0651 retval = arche_apb_init();
0652 if (retval)
0653 platform_driver_unregister(&arche_platform_device_driver);
0654
0655 return retval;
0656 }
0657 module_init(arche_init);
0658
0659 static void __exit arche_exit(void)
0660 {
0661 arche_apb_exit();
0662 platform_driver_unregister(&arche_platform_device_driver);
0663 }
0664 module_exit(arche_exit);
0665
0666 MODULE_LICENSE("GPL v2");
0667 MODULE_AUTHOR("Vaibhav Hiremath <vaibhav.hiremath@linaro.org>");
0668 MODULE_DESCRIPTION("Arche Platform Driver");