Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Arche Platform driver to enable Unipro link.
0004  *
0005  * Copyright 2014-2015 Google Inc.
0006  * Copyright 2014-2015 Linaro Ltd.
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,          /* Default state = pulled high/low */
0038     WD_STATE_BOOT_INIT,     /* WD = falling edge (low) */
0039     WD_STATE_COLDBOOT_TRIG,     /* WD = rising edge (high), > 30msec */
0040     WD_STATE_STANDBYBOOT_TRIG,  /* As of now not used ?? */
0041     WD_STATE_COLDBOOT_START,    /* Cold boot process started */
0042     WD_STATE_STANDBYBOOT_START, /* Not used */
0043 };
0044 
0045 struct arche_platform_drvdata {
0046     /* Control GPIO signals to and from AP <=> SVC */
0047     struct gpio_desc *svc_reset;
0048     bool is_reset_act_hi;
0049     struct gpio_desc *svc_sysboot;
0050     struct gpio_desc *wake_detect; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */
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;           /* Protect wake_detect_state */
0065     struct mutex platform_state_mutex;  /* Protect state */
0066     unsigned long wake_detect_start;
0067     struct notifier_block pm_notifier;
0068 
0069     struct device *dev;
0070 };
0071 
0072 /* Requires calling context to hold arche_pdata->platform_state_mutex */
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 /* Requires arche_pdata->wake_lock is held by calling context */
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     /*Child nodes are independent, so do not exit coldboot operation */
0100     return 0;
0101 }
0102 
0103 static int apb_poweroff(struct device *dev, void *data)
0104 {
0105     apb_ctrl_poweroff(dev);
0106 
0107     /* Enable HUB3613 into HUB mode. */
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     /* Enable interrupt here, to read event back from SVC */
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         /* Something is wrong */
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     /* It should complete power cycle, so first make sure it is poweroff */
0137     device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
0138 
0139     /* Bring APB out of reset: cold boot sequence */
0140     device_for_each_child(arche_pdata->dev, NULL, apb_cold_boot);
0141 
0142     /* Enable HUB3613 into HUB mode. */
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         /* wake/detect rising */
0162 
0163         /*
0164          * If wake/detect line goes high after low, within less than
0165          * 30msec, then standby boot sequence is initiated, which is not
0166          * supported/implemented as of now. So ignore it.
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                  * Check we are not in middle of irq thread
0177                  * already
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         /* wake/detect falling */
0191         if (arche_pdata->wake_detect_state == WD_STATE_IDLE) {
0192             arche_pdata->wake_detect_start = jiffies;
0193             /*
0194              * In the beginning, when wake/detect goes low
0195              * (first time), we assume it is meant for coldboot
0196              * and set the flag. If wake/detect line stays low
0197              * beyond 30msec, then it is coldboot else fallback
0198              * to standby boot.
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  * Requires arche_pdata->platform_state_mutex to be held
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     /* bring SVC out of reset */
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  * Requires arche_pdata->platform_state_mutex to be held
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  * Requires arche_pdata->platform_state_mutex to be held
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     /* If in fw_flashing mode, then no need to repeate things again */
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     /* As part of exit, put APB back in reset state */
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         /*  If SVC goes down, bring down APB's as well */
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         /* First we want to make sure we power off everything
0328          * and then activate back again
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          * Here we only control SVC.
0349          *
0350          * In case of FW_FLASHING mode we do not want to control
0351          * APBs, as in case of V2, SPI bus is shared between both
0352          * the APBs. So let user chose which APB he wants to flash.
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     /* setup svc reset gpio */
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     /* setup the clock request gpio first */
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     /* setup refclk2 to follow the pin */
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     /* Explicitly power off if requested */
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         /* TODO: Should we do anything more here ?? */
0574     return 0;
0575 }
0576 
0577 static __maybe_unused int arche_platform_suspend(struct device *dev)
0578 {
0579     /*
0580      * If timing profile premits, we may shutdown bridge
0581      * completely
0582      *
0583      * TODO: sequence ??
0584      *
0585      * Also, need to make sure we meet precondition for unipro suspend
0586      * Precondition: Definition ???
0587      */
0588     return 0;
0589 }
0590 
0591 static __maybe_unused int arche_platform_resume(struct device *dev)
0592 {
0593     /*
0594      * At least for ES2 we have to meet the delay requirement between
0595      * unipro switch and AP bridge init, depending on whether bridge is in
0596      * OFF state or standby state.
0597      *
0598      * Based on whether bridge is in standby or OFF state we may have to
0599      * assert multiple signals. Please refer to WDM spec, for more info.
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     /* Use PID/VID of SVC device */
0620     { .compatible = "google,arche-platform", },
0621     { },
0622 };
0623 
0624 static const struct of_device_id arche_combined_id[] = {
0625     /* Use PID/VID of SVC device */
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");