2 * Arche Platform driver to enable Unipro link.
4 * Copyright 2014-2015 Google Inc.
5 * Copyright 2014-2015 Linaro Ltd.
7 * Released under the GPLv2 only.
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/gpio.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/of_gpio.h>
16 #include <linux/of_platform.h>
17 #include <linux/pinctrl/consumer.h>
18 #include <linux/platform_device.h>
20 #include "arche_platform.h"
22 struct arche_platform_drvdata
{
23 /* Control GPIO signals to and from AP <=> SVC */
27 int wake_detect_gpio
; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */
29 unsigned int svc_refclk_req
;
30 struct clk
*svc_ref_clk
;
32 struct pinctrl
*pinctrl
;
33 struct pinctrl_state
*pin_default
;
37 struct delayed_work delayed_work
;
41 static inline void svc_reset_onoff(unsigned int gpio
, bool onoff
)
43 gpio_set_value(gpio
, onoff
);
47 * svc_delayed_work - Time to give SVC to boot.
49 static void svc_delayed_work(struct work_struct
*work
)
51 struct arche_platform_drvdata
*arche_pdata
=
52 container_of(work
, struct arche_platform_drvdata
, delayed_work
.work
);
53 struct device
*dev
= arche_pdata
->dev
;
54 struct device_node
*np
= dev
->of_node
;
59 * 1. SVC and AP boot independently, with AP<-->SVC wake/detect pin
60 * deasserted (LOW in this case)
61 * 2.1. SVC allows 360 milliseconds to elapse after switch boots to work
62 * around bug described in ENG-330.
63 * 2.2. AP asserts wake/detect pin (HIGH) (this can proceed in parallel with 2.1)
64 * 3. SVC detects assertion of wake/detect pin, and sends "wake out" signal to AP
65 * 4. AP receives "wake out" signal, takes AP Bridges through their power
66 * on reset sequence as defined in the bridge ASIC reference manuals
67 * 5. AP takes USB3613 through its power on reset sequence
68 * 6. AP enumerates AP Bridges
70 gpio_set_value(arche_pdata
->wake_detect_gpio
, 1);
71 gpio_direction_input(arche_pdata
->wake_detect_gpio
);
73 /* Read the wake_detect GPIO, for WAKE_OUT event from SVC */
74 if (gpio_get_value(arche_pdata
->wake_detect_gpio
) == 0)
81 ret
= of_platform_populate(np
, NULL
, NULL
, dev
);
83 /* Should we set wake_detect gpio to output again? */
87 /* FIXME: We may want to limit retries here */
88 gpio_direction_output(arche_pdata
->wake_detect_gpio
, 0);
89 schedule_delayed_work(&arche_pdata
->delayed_work
, msecs_to_jiffies(2000));
92 /* Export gpio's to user space */
93 static void export_gpios(struct arche_platform_drvdata
*arche_pdata
)
95 gpio_export(arche_pdata
->svc_reset_gpio
, false);
96 gpio_export(arche_pdata
->svc_sysboot_gpio
, false);
99 static void unexport_gpios(struct arche_platform_drvdata
*arche_pdata
)
101 gpio_unexport(arche_pdata
->svc_reset_gpio
);
102 gpio_unexport(arche_pdata
->svc_sysboot_gpio
);
105 static void arche_platform_cleanup(struct arche_platform_drvdata
*arche_pdata
)
107 clk_disable_unprepare(arche_pdata
->svc_ref_clk
);
108 /* As part of exit, put APB back in reset state */
109 svc_reset_onoff(arche_pdata
->svc_reset_gpio
,
110 arche_pdata
->is_reset_act_hi
);
113 static int arche_platform_probe(struct platform_device
*pdev
)
115 struct arche_platform_drvdata
*arche_pdata
;
116 struct device
*dev
= &pdev
->dev
;
117 struct device_node
*np
= dev
->of_node
;
120 arche_pdata
= devm_kzalloc(&pdev
->dev
, sizeof(*arche_pdata
), GFP_KERNEL
);
124 /* setup svc reset gpio */
125 arche_pdata
->is_reset_act_hi
= of_property_read_bool(np
,
126 "svc,reset-active-high");
127 arche_pdata
->svc_reset_gpio
= of_get_named_gpio(np
, "svc,reset-gpio", 0);
128 if (arche_pdata
->svc_reset_gpio
< 0) {
129 dev_err(dev
, "failed to get reset-gpio\n");
130 return arche_pdata
->svc_reset_gpio
;
132 ret
= devm_gpio_request(dev
, arche_pdata
->svc_reset_gpio
, "svc-reset");
134 dev_err(dev
, "failed to request svc-reset gpio:%d\n", ret
);
137 ret
= gpio_direction_output(arche_pdata
->svc_reset_gpio
,
138 arche_pdata
->is_reset_act_hi
);
140 dev_err(dev
, "failed to set svc-reset gpio dir:%d\n", ret
);
144 arche_pdata
->svc_sysboot_gpio
= of_get_named_gpio(np
,
145 "svc,sysboot-gpio", 0);
146 if (arche_pdata
->svc_sysboot_gpio
< 0) {
147 dev_err(dev
, "failed to get sysboot gpio\n");
148 return arche_pdata
->svc_sysboot_gpio
;
150 ret
= devm_gpio_request(dev
, arche_pdata
->svc_sysboot_gpio
, "sysboot0");
152 dev_err(dev
, "failed to request sysboot0 gpio:%d\n", ret
);
155 ret
= gpio_direction_output(arche_pdata
->svc_sysboot_gpio
, 0);
157 dev_err(dev
, "failed to set svc-reset gpio dir:%d\n", ret
);
161 /* setup the clock request gpio first */
162 arche_pdata
->svc_refclk_req
= of_get_named_gpio(np
,
163 "svc,refclk-req-gpio", 0);
164 if (arche_pdata
->svc_refclk_req
< 0) {
165 dev_err(dev
, "failed to get svc clock-req gpio\n");
166 return arche_pdata
->svc_refclk_req
;
168 ret
= devm_gpio_request(dev
, arche_pdata
->svc_refclk_req
, "svc-clk-req");
170 dev_err(dev
, "failed to request svc-clk-req gpio: %d\n", ret
);
173 ret
= gpio_direction_input(arche_pdata
->svc_refclk_req
);
175 dev_err(dev
, "failed to set svc-clk-req gpio dir :%d\n", ret
);
179 /* setup refclk2 to follow the pin */
180 arche_pdata
->svc_ref_clk
= devm_clk_get(dev
, "svc_ref_clk");
181 if (IS_ERR(arche_pdata
->svc_ref_clk
)) {
182 ret
= PTR_ERR(arche_pdata
->svc_ref_clk
);
183 dev_err(dev
, "failed to get svc_ref_clk: %d\n", ret
);
186 ret
= clk_prepare_enable(arche_pdata
->svc_ref_clk
);
188 dev_err(dev
, "failed to enable svc_ref_clk: %d\n", ret
);
192 platform_set_drvdata(pdev
, arche_pdata
);
194 /* bring SVC out of reset */
195 svc_reset_onoff(arche_pdata
->svc_reset_gpio
,
196 !arche_pdata
->is_reset_act_hi
);
198 arche_pdata
->num_apbs
= of_get_child_count(np
);
199 dev_dbg(dev
, "Number of APB's available - %d\n", arche_pdata
->num_apbs
);
201 arche_pdata
->wake_detect_gpio
= of_get_named_gpio(np
, "svc,wake-detect-gpio", 0);
202 if (arche_pdata
->wake_detect_gpio
< 0) {
203 dev_err(dev
, "failed to get wake detect gpio\n");
204 ret
= arche_pdata
->wake_detect_gpio
;
208 ret
= devm_gpio_request(dev
, arche_pdata
->wake_detect_gpio
, "wake detect");
210 dev_err(dev
, "Failed requesting wake_detect gpio %d\n",
211 arche_pdata
->wake_detect_gpio
);
214 /* deassert wake detect */
215 gpio_direction_output(arche_pdata
->wake_detect_gpio
, 0);
217 arche_pdata
->dev
= &pdev
->dev
;
218 INIT_DELAYED_WORK(&arche_pdata
->delayed_work
, svc_delayed_work
);
219 schedule_delayed_work(&arche_pdata
->delayed_work
, msecs_to_jiffies(2000));
221 export_gpios(arche_pdata
);
223 dev_info(dev
, "Device registered successfully\n");
227 arche_platform_cleanup(arche_pdata
);
231 static int arche_remove_child(struct device
*dev
, void *unused
)
233 struct platform_device
*pdev
= to_platform_device(dev
);
235 platform_device_unregister(pdev
);
240 static int arche_platform_remove(struct platform_device
*pdev
)
242 struct arche_platform_drvdata
*arche_pdata
= platform_get_drvdata(pdev
);
244 device_for_each_child(&pdev
->dev
, NULL
, arche_remove_child
);
245 arche_platform_cleanup(arche_pdata
);
246 platform_set_drvdata(pdev
, NULL
);
247 unexport_gpios(arche_pdata
);
252 static int arche_platform_suspend(struct device
*dev
)
255 * If timing profile premits, we may shutdown bridge
260 * Also, need to make sure we meet precondition for unipro suspend
261 * Precondition: Definition ???
266 static int arche_platform_resume(struct device
*dev
)
269 * Atleast for ES2 we have to meet the delay requirement between
270 * unipro switch and AP bridge init, depending on whether bridge is in
271 * OFF state or standby state.
273 * Based on whether bridge is in standby or OFF state we may have to
274 * assert multiple signals. Please refer to WDM spec, for more info.
280 static SIMPLE_DEV_PM_OPS(arche_platform_pm_ops
,
281 arche_platform_suspend
,
282 arche_platform_resume
);
284 static struct of_device_id arche_platform_of_match
[] = {
285 { .compatible
= "google,arche-platform", }, /* Use PID/VID of SVC device */
289 static struct of_device_id arche_apb_ctrl_of_match
[] = {
290 { .compatible
= "usbffff,2", },
294 static struct of_device_id arche_combined_id
[] = {
295 { .compatible
= "google,arche-platform", }, /* Use PID/VID of SVC device */
296 { .compatible
= "usbffff,2", },
299 MODULE_DEVICE_TABLE(of
, arche_combined_id
);
301 static struct platform_driver arche_platform_device_driver
= {
302 .probe
= arche_platform_probe
,
303 .remove
= arche_platform_remove
,
305 .name
= "arche-platform-ctrl",
306 .pm
= &arche_platform_pm_ops
,
307 .of_match_table
= arche_platform_of_match
,
311 static struct platform_driver arche_apb_ctrl_device_driver
= {
312 .probe
= arche_apb_ctrl_probe
,
313 .remove
= arche_apb_ctrl_remove
,
315 .name
= "arche-apb-ctrl",
316 .pm
= &arche_apb_ctrl_pm_ops
,
317 .of_match_table
= arche_apb_ctrl_of_match
,
321 static int __init
arche_init(void)
325 retval
= platform_driver_register(&arche_platform_device_driver
);
329 retval
= platform_driver_register(&arche_apb_ctrl_device_driver
);
331 platform_driver_unregister(&arche_platform_device_driver
);
335 module_init(arche_init
);
337 static void __exit
arche_exit(void)
339 platform_driver_unregister(&arche_apb_ctrl_device_driver
);
340 platform_driver_unregister(&arche_platform_device_driver
);
342 module_exit(arche_exit
);
344 MODULE_LICENSE("GPL");
345 MODULE_AUTHOR("Vaibhav Hiremath <vaibhav.hiremath@linaro.org>");
346 MODULE_DESCRIPTION("Arche Platform Driver");