root/drivers/staging/greybus/arche-platform.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usb3613_hub_mode_ctrl
  2. arche_platform_set_state
  3. arche_platform_set_wake_detect_state
  4. svc_reset_onoff
  5. apb_cold_boot
  6. apb_poweroff
  7. arche_platform_wd_irq_en
  8. arche_platform_wd_irq_thread
  9. arche_platform_wd_irq
  10. arche_platform_coldboot_seq
  11. arche_platform_fw_flashing_seq
  12. arche_platform_poweroff_seq
  13. state_store
  14. state_show
  15. arche_platform_pm_notifier
  16. arche_platform_probe
  17. arche_remove_child
  18. arche_platform_remove
  19. arche_platform_suspend
  20. arche_platform_resume
  21. arche_platform_shutdown
  22. arche_init
  23. arche_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Arche Platform driver to enable Unipro link.
   4  *
   5  * Copyright 2014-2015 Google Inc.
   6  * Copyright 2014-2015 Linaro Ltd.
   7  */
   8 
   9 #include <linux/clk.h>
  10 #include <linux/delay.h>
  11 #include <linux/gpio/consumer.h>
  12 #include <linux/init.h>
  13 #include <linux/module.h>
  14 #include <linux/of_platform.h>
  15 #include <linux/pinctrl/consumer.h>
  16 #include <linux/platform_device.h>
  17 #include <linux/pm.h>
  18 #include <linux/interrupt.h>
  19 #include <linux/irq.h>
  20 #include <linux/suspend.h>
  21 #include <linux/time.h>
  22 #include <linux/greybus.h>
  23 #include "arche_platform.h"
  24 
  25 #if IS_ENABLED(CONFIG_USB_HSIC_USB3613)
  26 #include <linux/usb/usb3613.h>
  27 #else
  28 static inline int usb3613_hub_mode_ctrl(bool unused)
  29 {
  30         return 0;
  31 }
  32 #endif
  33 
  34 #define WD_COLDBOOT_PULSE_WIDTH_MS      30
  35 
  36 enum svc_wakedetect_state {
  37         WD_STATE_IDLE,                  /* Default state = pulled high/low */
  38         WD_STATE_BOOT_INIT,             /* WD = falling edge (low) */
  39         WD_STATE_COLDBOOT_TRIG,         /* WD = rising edge (high), > 30msec */
  40         WD_STATE_STANDBYBOOT_TRIG,      /* As of now not used ?? */
  41         WD_STATE_COLDBOOT_START,        /* Cold boot process started */
  42         WD_STATE_STANDBYBOOT_START,     /* Not used */
  43 };
  44 
  45 struct arche_platform_drvdata {
  46         /* Control GPIO signals to and from AP <=> SVC */
  47         struct gpio_desc *svc_reset;
  48         bool is_reset_act_hi;
  49         struct gpio_desc *svc_sysboot;
  50         struct gpio_desc *wake_detect; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */
  51 
  52         enum arche_platform_state state;
  53 
  54         struct gpio_desc *svc_refclk_req;
  55         struct clk *svc_ref_clk;
  56 
  57         struct pinctrl *pinctrl;
  58         struct pinctrl_state *pin_default;
  59 
  60         int num_apbs;
  61 
  62         enum svc_wakedetect_state wake_detect_state;
  63         int wake_detect_irq;
  64         spinlock_t wake_lock;                   /* Protect wake_detect_state */
  65         struct mutex platform_state_mutex;      /* Protect state */
  66         unsigned long wake_detect_start;
  67         struct notifier_block pm_notifier;
  68 
  69         struct device *dev;
  70 };
  71 
  72 /* Requires calling context to hold arche_pdata->platform_state_mutex */
  73 static void arche_platform_set_state(struct arche_platform_drvdata *arche_pdata,
  74                                      enum arche_platform_state state)
  75 {
  76         arche_pdata->state = state;
  77 }
  78 
  79 /* Requires arche_pdata->wake_lock is held by calling context */
  80 static void arche_platform_set_wake_detect_state(
  81                                 struct arche_platform_drvdata *arche_pdata,
  82                                 enum svc_wakedetect_state state)
  83 {
  84         arche_pdata->wake_detect_state = state;
  85 }
  86 
  87 static inline void svc_reset_onoff(struct gpio_desc *gpio, bool onoff)
  88 {
  89         gpiod_set_raw_value(gpio, onoff);
  90 }
  91 
  92 static int apb_cold_boot(struct device *dev, void *data)
  93 {
  94         int ret;
  95 
  96         ret = apb_ctrl_coldboot(dev);
  97         if (ret)
  98                 dev_warn(dev, "failed to coldboot\n");
  99 
 100         /*Child nodes are independent, so do not exit coldboot operation */
 101         return 0;
 102 }
 103 
 104 static int apb_poweroff(struct device *dev, void *data)
 105 {
 106         apb_ctrl_poweroff(dev);
 107 
 108         /* Enable HUB3613 into HUB mode. */
 109         if (usb3613_hub_mode_ctrl(false))
 110                 dev_warn(dev, "failed to control hub device\n");
 111 
 112         return 0;
 113 }
 114 
 115 static void arche_platform_wd_irq_en(struct arche_platform_drvdata *arche_pdata)
 116 {
 117         /* Enable interrupt here, to read event back from SVC */
 118         enable_irq(arche_pdata->wake_detect_irq);
 119 }
 120 
 121 static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid)
 122 {
 123         struct arche_platform_drvdata *arche_pdata = devid;
 124         unsigned long flags;
 125 
 126         spin_lock_irqsave(&arche_pdata->wake_lock, flags);
 127         if (arche_pdata->wake_detect_state != WD_STATE_COLDBOOT_TRIG) {
 128                 /* Something is wrong */
 129                 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
 130                 return IRQ_HANDLED;
 131         }
 132 
 133         arche_platform_set_wake_detect_state(arche_pdata,
 134                                              WD_STATE_COLDBOOT_START);
 135         spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
 136 
 137         /* It should complete power cycle, so first make sure it is poweroff */
 138         device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
 139 
 140         /* Bring APB out of reset: cold boot sequence */
 141         device_for_each_child(arche_pdata->dev, NULL, apb_cold_boot);
 142 
 143         /* Enable HUB3613 into HUB mode. */
 144         if (usb3613_hub_mode_ctrl(true))
 145                 dev_warn(arche_pdata->dev, "failed to control hub device\n");
 146 
 147         spin_lock_irqsave(&arche_pdata->wake_lock, flags);
 148         arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);
 149         spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
 150 
 151         return IRQ_HANDLED;
 152 }
 153 
 154 static irqreturn_t arche_platform_wd_irq(int irq, void *devid)
 155 {
 156         struct arche_platform_drvdata *arche_pdata = devid;
 157         unsigned long flags;
 158 
 159         spin_lock_irqsave(&arche_pdata->wake_lock, flags);
 160 
 161         if (gpiod_get_value(arche_pdata->wake_detect)) {
 162                 /* wake/detect rising */
 163 
 164                 /*
 165                  * If wake/detect line goes high after low, within less than
 166                  * 30msec, then standby boot sequence is initiated, which is not
 167                  * supported/implemented as of now. So ignore it.
 168                  */
 169                 if (arche_pdata->wake_detect_state == WD_STATE_BOOT_INIT) {
 170                         if (time_before(jiffies,
 171                                         arche_pdata->wake_detect_start +
 172                                         msecs_to_jiffies(WD_COLDBOOT_PULSE_WIDTH_MS))) {
 173                                 arche_platform_set_wake_detect_state(arche_pdata,
 174                                                                      WD_STATE_IDLE);
 175                         } else {
 176                                 /*
 177                                  * Check we are not in middle of irq thread
 178                                  * already
 179                                  */
 180                                 if (arche_pdata->wake_detect_state !=
 181                                                 WD_STATE_COLDBOOT_START) {
 182                                         arche_platform_set_wake_detect_state(arche_pdata,
 183                                                                              WD_STATE_COLDBOOT_TRIG);
 184                                         spin_unlock_irqrestore(
 185                                                 &arche_pdata->wake_lock,
 186                                                 flags);
 187                                         return IRQ_WAKE_THREAD;
 188                                 }
 189                         }
 190                 }
 191         } else {
 192                 /* wake/detect falling */
 193                 if (arche_pdata->wake_detect_state == WD_STATE_IDLE) {
 194                         arche_pdata->wake_detect_start = jiffies;
 195                         /*
 196                          * In the beginning, when wake/detect goes low
 197                          * (first time), we assume it is meant for coldboot
 198                          * and set the flag. If wake/detect line stays low
 199                          * beyond 30msec, then it is coldboot else fallback
 200                          * to standby boot.
 201                          */
 202                         arche_platform_set_wake_detect_state(arche_pdata,
 203                                                              WD_STATE_BOOT_INIT);
 204                 }
 205         }
 206 
 207         spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
 208 
 209         return IRQ_HANDLED;
 210 }
 211 
 212 /*
 213  * Requires arche_pdata->platform_state_mutex to be held
 214  */
 215 static int
 216 arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata)
 217 {
 218         int ret;
 219 
 220         if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE)
 221                 return 0;
 222 
 223         dev_info(arche_pdata->dev, "Booting from cold boot state\n");
 224 
 225         svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi);
 226 
 227         gpiod_set_value(arche_pdata->svc_sysboot, 0);
 228         usleep_range(100, 200);
 229 
 230         ret = clk_prepare_enable(arche_pdata->svc_ref_clk);
 231         if (ret) {
 232                 dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n",
 233                         ret);
 234                 return ret;
 235         }
 236 
 237         /* bring SVC out of reset */
 238         svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi);
 239 
 240         arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_ACTIVE);
 241 
 242         return 0;
 243 }
 244 
 245 /*
 246  * Requires arche_pdata->platform_state_mutex to be held
 247  */
 248 static int
 249 arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata)
 250 {
 251         int ret;
 252 
 253         if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
 254                 return 0;
 255 
 256         dev_info(arche_pdata->dev, "Switching to FW flashing state\n");
 257 
 258         svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi);
 259 
 260         gpiod_set_value(arche_pdata->svc_sysboot, 1);
 261 
 262         usleep_range(100, 200);
 263 
 264         ret = clk_prepare_enable(arche_pdata->svc_ref_clk);
 265         if (ret) {
 266                 dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n",
 267                         ret);
 268                 return ret;
 269         }
 270 
 271         svc_reset_onoff(arche_pdata->svc_reset, !arche_pdata->is_reset_act_hi);
 272 
 273         arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_FW_FLASHING);
 274 
 275         return 0;
 276 }
 277 
 278 /*
 279  * Requires arche_pdata->platform_state_mutex to be held
 280  */
 281 static void
 282 arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata)
 283 {
 284         unsigned long flags;
 285 
 286         if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF)
 287                 return;
 288 
 289         /* If in fw_flashing mode, then no need to repeate things again */
 290         if (arche_pdata->state != ARCHE_PLATFORM_STATE_FW_FLASHING) {
 291                 disable_irq(arche_pdata->wake_detect_irq);
 292 
 293                 spin_lock_irqsave(&arche_pdata->wake_lock, flags);
 294                 arche_platform_set_wake_detect_state(arche_pdata,
 295                                                      WD_STATE_IDLE);
 296                 spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
 297         }
 298 
 299         clk_disable_unprepare(arche_pdata->svc_ref_clk);
 300 
 301         /* As part of exit, put APB back in reset state */
 302         svc_reset_onoff(arche_pdata->svc_reset, arche_pdata->is_reset_act_hi);
 303 
 304         arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);
 305 }
 306 
 307 static ssize_t state_store(struct device *dev,
 308                            struct device_attribute *attr,
 309                            const char *buf, size_t count)
 310 {
 311         struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev);
 312         int ret = 0;
 313 
 314         mutex_lock(&arche_pdata->platform_state_mutex);
 315 
 316         if (sysfs_streq(buf, "off")) {
 317                 if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF)
 318                         goto exit;
 319 
 320                 /*  If SVC goes down, bring down APB's as well */
 321                 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
 322 
 323                 arche_platform_poweroff_seq(arche_pdata);
 324 
 325         } else if (sysfs_streq(buf, "active")) {
 326                 if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE)
 327                         goto exit;
 328 
 329                 /* First we want to make sure we power off everything
 330                  * and then activate back again
 331                  */
 332                 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
 333                 arche_platform_poweroff_seq(arche_pdata);
 334 
 335                 arche_platform_wd_irq_en(arche_pdata);
 336                 ret = arche_platform_coldboot_seq(arche_pdata);
 337                 if (ret)
 338                         goto exit;
 339 
 340         } else if (sysfs_streq(buf, "standby")) {
 341                 if (arche_pdata->state == ARCHE_PLATFORM_STATE_STANDBY)
 342                         goto exit;
 343 
 344                 dev_warn(arche_pdata->dev, "standby state not supported\n");
 345         } else if (sysfs_streq(buf, "fw_flashing")) {
 346                 if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
 347                         goto exit;
 348 
 349                 /*
 350                  * Here we only control SVC.
 351                  *
 352                  * In case of FW_FLASHING mode we do not want to control
 353                  * APBs, as in case of V2, SPI bus is shared between both
 354                  * the APBs. So let user chose which APB he wants to flash.
 355                  */
 356                 arche_platform_poweroff_seq(arche_pdata);
 357 
 358                 ret = arche_platform_fw_flashing_seq(arche_pdata);
 359                 if (ret)
 360                         goto exit;
 361         } else {
 362                 dev_err(arche_pdata->dev, "unknown state\n");
 363                 ret = -EINVAL;
 364         }
 365 
 366 exit:
 367         mutex_unlock(&arche_pdata->platform_state_mutex);
 368         return ret ? ret : count;
 369 }
 370 
 371 static ssize_t state_show(struct device *dev,
 372                           struct device_attribute *attr, char *buf)
 373 {
 374         struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev);
 375 
 376         switch (arche_pdata->state) {
 377         case ARCHE_PLATFORM_STATE_OFF:
 378                 return sprintf(buf, "off\n");
 379         case ARCHE_PLATFORM_STATE_ACTIVE:
 380                 return sprintf(buf, "active\n");
 381         case ARCHE_PLATFORM_STATE_STANDBY:
 382                 return sprintf(buf, "standby\n");
 383         case ARCHE_PLATFORM_STATE_FW_FLASHING:
 384                 return sprintf(buf, "fw_flashing\n");
 385         default:
 386                 return sprintf(buf, "unknown state\n");
 387         }
 388 }
 389 
 390 static DEVICE_ATTR_RW(state);
 391 
 392 static int arche_platform_pm_notifier(struct notifier_block *notifier,
 393                                       unsigned long pm_event, void *unused)
 394 {
 395         struct arche_platform_drvdata *arche_pdata =
 396                 container_of(notifier, struct arche_platform_drvdata,
 397                              pm_notifier);
 398         int ret = NOTIFY_DONE;
 399 
 400         mutex_lock(&arche_pdata->platform_state_mutex);
 401         switch (pm_event) {
 402         case PM_SUSPEND_PREPARE:
 403                 if (arche_pdata->state != ARCHE_PLATFORM_STATE_ACTIVE) {
 404                         ret = NOTIFY_STOP;
 405                         break;
 406                 }
 407                 device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
 408                 arche_platform_poweroff_seq(arche_pdata);
 409                 break;
 410         case PM_POST_SUSPEND:
 411                 if (arche_pdata->state != ARCHE_PLATFORM_STATE_OFF)
 412                         break;
 413 
 414                 arche_platform_wd_irq_en(arche_pdata);
 415                 arche_platform_coldboot_seq(arche_pdata);
 416                 break;
 417         default:
 418                 break;
 419         }
 420         mutex_unlock(&arche_pdata->platform_state_mutex);
 421 
 422         return ret;
 423 }
 424 
 425 static int arche_platform_probe(struct platform_device *pdev)
 426 {
 427         struct arche_platform_drvdata *arche_pdata;
 428         struct device *dev = &pdev->dev;
 429         struct device_node *np = dev->of_node;
 430         int ret;
 431         unsigned int flags;
 432 
 433         arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata),
 434                                    GFP_KERNEL);
 435         if (!arche_pdata)
 436                 return -ENOMEM;
 437 
 438         /* setup svc reset gpio */
 439         arche_pdata->is_reset_act_hi = of_property_read_bool(np,
 440                                                              "svc,reset-active-high");
 441         if (arche_pdata->is_reset_act_hi)
 442                 flags = GPIOD_OUT_HIGH;
 443         else
 444                 flags = GPIOD_OUT_LOW;
 445 
 446         arche_pdata->svc_reset = devm_gpiod_get(dev, "svc,reset", flags);
 447         if (IS_ERR(arche_pdata->svc_reset)) {
 448                 ret = PTR_ERR(arche_pdata->svc_reset);
 449                 dev_err(dev, "failed to request svc-reset GPIO: %d\n", ret);
 450                 return ret;
 451         }
 452         arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);
 453 
 454         arche_pdata->svc_sysboot = devm_gpiod_get(dev, "svc,sysboot",
 455                                                   GPIOD_OUT_LOW);
 456         if (IS_ERR(arche_pdata->svc_sysboot)) {
 457                 ret = PTR_ERR(arche_pdata->svc_sysboot);
 458                 dev_err(dev, "failed to request sysboot0 GPIO: %d\n", ret);
 459                 return ret;
 460         }
 461 
 462         /* setup the clock request gpio first */
 463         arche_pdata->svc_refclk_req = devm_gpiod_get(dev, "svc,refclk-req",
 464                                                      GPIOD_IN);
 465         if (IS_ERR(arche_pdata->svc_refclk_req)) {
 466                 ret = PTR_ERR(arche_pdata->svc_refclk_req);
 467                 dev_err(dev, "failed to request svc-clk-req GPIO: %d\n", ret);
 468                 return ret;
 469         }
 470 
 471         /* setup refclk2 to follow the pin */
 472         arche_pdata->svc_ref_clk = devm_clk_get(dev, "svc_ref_clk");
 473         if (IS_ERR(arche_pdata->svc_ref_clk)) {
 474                 ret = PTR_ERR(arche_pdata->svc_ref_clk);
 475                 dev_err(dev, "failed to get svc_ref_clk: %d\n", ret);
 476                 return ret;
 477         }
 478 
 479         platform_set_drvdata(pdev, arche_pdata);
 480 
 481         arche_pdata->num_apbs = of_get_child_count(np);
 482         dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs);
 483 
 484         arche_pdata->wake_detect = devm_gpiod_get(dev, "svc,wake-detect",
 485                                                   GPIOD_IN);
 486         if (IS_ERR(arche_pdata->wake_detect)) {
 487                 ret = PTR_ERR(arche_pdata->wake_detect);
 488                 dev_err(dev, "Failed requesting wake_detect GPIO: %d\n", ret);
 489                 return ret;
 490         }
 491 
 492         arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);
 493 
 494         arche_pdata->dev = &pdev->dev;
 495 
 496         spin_lock_init(&arche_pdata->wake_lock);
 497         mutex_init(&arche_pdata->platform_state_mutex);
 498         arche_pdata->wake_detect_irq =
 499                 gpiod_to_irq(arche_pdata->wake_detect);
 500 
 501         ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq,
 502                                         arche_platform_wd_irq,
 503                                         arche_platform_wd_irq_thread,
 504                                         IRQF_TRIGGER_FALLING |
 505                                         IRQF_TRIGGER_RISING | IRQF_ONESHOT,
 506                                         dev_name(dev), arche_pdata);
 507         if (ret) {
 508                 dev_err(dev, "failed to request wake detect IRQ %d\n", ret);
 509                 return ret;
 510         }
 511         disable_irq(arche_pdata->wake_detect_irq);
 512 
 513         ret = device_create_file(dev, &dev_attr_state);
 514         if (ret) {
 515                 dev_err(dev, "failed to create state file in sysfs\n");
 516                 return ret;
 517         }
 518 
 519         ret = of_platform_populate(np, NULL, NULL, dev);
 520         if (ret) {
 521                 dev_err(dev, "failed to populate child nodes %d\n", ret);
 522                 goto err_device_remove;
 523         }
 524 
 525         arche_pdata->pm_notifier.notifier_call = arche_platform_pm_notifier;
 526         ret = register_pm_notifier(&arche_pdata->pm_notifier);
 527 
 528         if (ret) {
 529                 dev_err(dev, "failed to register pm notifier %d\n", ret);
 530                 goto err_device_remove;
 531         }
 532 
 533         /* Explicitly power off if requested */
 534         if (!of_property_read_bool(pdev->dev.of_node, "arche,init-off")) {
 535                 mutex_lock(&arche_pdata->platform_state_mutex);
 536                 ret = arche_platform_coldboot_seq(arche_pdata);
 537                 if (ret) {
 538                         dev_err(dev, "Failed to cold boot svc %d\n", ret);
 539                         goto err_coldboot;
 540                 }
 541                 arche_platform_wd_irq_en(arche_pdata);
 542                 mutex_unlock(&arche_pdata->platform_state_mutex);
 543         }
 544 
 545         dev_info(dev, "Device registered successfully\n");
 546         return 0;
 547 
 548 err_coldboot:
 549         mutex_unlock(&arche_pdata->platform_state_mutex);
 550 err_device_remove:
 551         device_remove_file(&pdev->dev, &dev_attr_state);
 552         return ret;
 553 }
 554 
 555 static int arche_remove_child(struct device *dev, void *unused)
 556 {
 557         struct platform_device *pdev = to_platform_device(dev);
 558 
 559         platform_device_unregister(pdev);
 560 
 561         return 0;
 562 }
 563 
 564 static int arche_platform_remove(struct platform_device *pdev)
 565 {
 566         struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev);
 567 
 568         unregister_pm_notifier(&arche_pdata->pm_notifier);
 569         device_remove_file(&pdev->dev, &dev_attr_state);
 570         device_for_each_child(&pdev->dev, NULL, arche_remove_child);
 571         arche_platform_poweroff_seq(arche_pdata);
 572 
 573         if (usb3613_hub_mode_ctrl(false))
 574                 dev_warn(arche_pdata->dev, "failed to control hub device\n");
 575                 /* TODO: Should we do anything more here ?? */
 576         return 0;
 577 }
 578 
 579 static __maybe_unused int arche_platform_suspend(struct device *dev)
 580 {
 581         /*
 582          * If timing profile premits, we may shutdown bridge
 583          * completely
 584          *
 585          * TODO: sequence ??
 586          *
 587          * Also, need to make sure we meet precondition for unipro suspend
 588          * Precondition: Definition ???
 589          */
 590         return 0;
 591 }
 592 
 593 static __maybe_unused int arche_platform_resume(struct device *dev)
 594 {
 595         /*
 596          * Atleast for ES2 we have to meet the delay requirement between
 597          * unipro switch and AP bridge init, depending on whether bridge is in
 598          * OFF state or standby state.
 599          *
 600          * Based on whether bridge is in standby or OFF state we may have to
 601          * assert multiple signals. Please refer to WDM spec, for more info.
 602          *
 603          */
 604         return 0;
 605 }
 606 
 607 static void arche_platform_shutdown(struct platform_device *pdev)
 608 {
 609         struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev);
 610 
 611         arche_platform_poweroff_seq(arche_pdata);
 612 
 613         usb3613_hub_mode_ctrl(false);
 614 }
 615 
 616 static SIMPLE_DEV_PM_OPS(arche_platform_pm_ops,
 617                         arche_platform_suspend,
 618                         arche_platform_resume);
 619 
 620 static const struct of_device_id arche_platform_of_match[] = {
 621         /* Use PID/VID of SVC device */
 622         { .compatible = "google,arche-platform", },
 623         { },
 624 };
 625 
 626 static const struct of_device_id arche_combined_id[] = {
 627         /* Use PID/VID of SVC device */
 628         { .compatible = "google,arche-platform", },
 629         { .compatible = "usbffff,2", },
 630         { },
 631 };
 632 MODULE_DEVICE_TABLE(of, arche_combined_id);
 633 
 634 static struct platform_driver arche_platform_device_driver = {
 635         .probe          = arche_platform_probe,
 636         .remove         = arche_platform_remove,
 637         .shutdown       = arche_platform_shutdown,
 638         .driver         = {
 639                 .name   = "arche-platform-ctrl",
 640                 .pm     = &arche_platform_pm_ops,
 641                 .of_match_table = arche_platform_of_match,
 642         }
 643 };
 644 
 645 static int __init arche_init(void)
 646 {
 647         int retval;
 648 
 649         retval = platform_driver_register(&arche_platform_device_driver);
 650         if (retval)
 651                 return retval;
 652 
 653         retval = arche_apb_init();
 654         if (retval)
 655                 platform_driver_unregister(&arche_platform_device_driver);
 656 
 657         return retval;
 658 }
 659 module_init(arche_init);
 660 
 661 static void __exit arche_exit(void)
 662 {
 663         arche_apb_exit();
 664         platform_driver_unregister(&arche_platform_device_driver);
 665 }
 666 module_exit(arche_exit);
 667 
 668 MODULE_LICENSE("GPL v2");
 669 MODULE_AUTHOR("Vaibhav Hiremath <vaibhav.hiremath@linaro.org>");
 670 MODULE_DESCRIPTION("Arche Platform Driver");

/* [<][>][^][v][top][bottom][index][help] */