25
25
#include <linux/errno.h>
26
26
#include <linux/skbuff.h>
27
27
#include <linux/firmware.h>
28
+ #include <linux/module.h>
29
+ #include <linux/acpi.h>
30
+ #include <linux/platform_device.h>
31
+ #include <linux/clk.h>
32
+ #include <linux/gpio/consumer.h>
33
+ #include <linux/tty.h>
28
34
29
35
#include <net/bluetooth/bluetooth.h>
30
36
#include <net/bluetooth/hci_core.h>
31
37
32
38
#include "btbcm.h"
33
39
#include "hci_uart.h"
34
40
41
+ struct bcm_device {
42
+ struct list_head list ;
43
+
44
+ struct platform_device * pdev ;
45
+
46
+ const char * name ;
47
+ struct gpio_desc * device_wakeup ;
48
+ struct gpio_desc * shutdown ;
49
+
50
+ struct clk * clk ;
51
+ bool clk_enabled ;
52
+ };
53
+
35
54
struct bcm_data {
36
- struct sk_buff * rx_skb ;
37
- struct sk_buff_head txq ;
55
+ struct sk_buff * rx_skb ;
56
+ struct sk_buff_head txq ;
57
+
58
+ struct bcm_device * dev ;
38
59
};
39
60
61
+ /* List of BCM BT UART devices */
62
+ static DEFINE_SPINLOCK (bcm_device_list_lock );
63
+ static LIST_HEAD (bcm_device_list );
64
+
40
65
static int bcm_set_baudrate (struct hci_uart * hu , unsigned int speed )
41
66
{
42
67
struct hci_dev * hdev = hu -> hdev ;
@@ -86,9 +111,41 @@ static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
86
111
return 0 ;
87
112
}
88
113
114
+ /* bcm_device_exists should be protected by bcm_device_list_lock */
115
+ static bool bcm_device_exists (struct bcm_device * device )
116
+ {
117
+ struct list_head * p ;
118
+
119
+ list_for_each (p , & bcm_device_list ) {
120
+ struct bcm_device * dev = list_entry (p , struct bcm_device , list );
121
+
122
+ if (device == dev )
123
+ return true;
124
+ }
125
+
126
+ return false;
127
+ }
128
+
129
+ static int bcm_gpio_set_power (struct bcm_device * dev , bool powered )
130
+ {
131
+ if (powered && !IS_ERR (dev -> clk ) && !dev -> clk_enabled )
132
+ clk_enable (dev -> clk );
133
+
134
+ gpiod_set_value_cansleep (dev -> shutdown , powered );
135
+ gpiod_set_value_cansleep (dev -> device_wakeup , powered );
136
+
137
+ if (!powered && !IS_ERR (dev -> clk ) && dev -> clk_enabled )
138
+ clk_disable (dev -> clk );
139
+
140
+ dev -> clk_enabled = powered ;
141
+
142
+ return 0 ;
143
+ }
144
+
89
145
static int bcm_open (struct hci_uart * hu )
90
146
{
91
147
struct bcm_data * bcm ;
148
+ struct list_head * p ;
92
149
93
150
BT_DBG ("hu %p" , hu );
94
151
@@ -99,6 +156,26 @@ static int bcm_open(struct hci_uart *hu)
99
156
skb_queue_head_init (& bcm -> txq );
100
157
101
158
hu -> priv = bcm ;
159
+
160
+ spin_lock (& bcm_device_list_lock );
161
+ list_for_each (p , & bcm_device_list ) {
162
+ struct bcm_device * dev = list_entry (p , struct bcm_device , list );
163
+
164
+ /* Retrieve saved bcm_device based on parent of the
165
+ * platform device (saved during device probe) and
166
+ * parent of tty device used by hci_uart
167
+ */
168
+ if (hu -> tty -> dev -> parent == dev -> pdev -> dev .parent ) {
169
+ bcm -> dev = dev ;
170
+ break ;
171
+ }
172
+ }
173
+
174
+ if (bcm -> dev )
175
+ bcm_gpio_set_power (bcm -> dev , true);
176
+
177
+ spin_unlock (& bcm_device_list_lock );
178
+
102
179
return 0 ;
103
180
}
104
181
@@ -108,6 +185,12 @@ static int bcm_close(struct hci_uart *hu)
108
185
109
186
BT_DBG ("hu %p" , hu );
110
187
188
+ /* Protect bcm->dev against removal of the device or driver */
189
+ spin_lock (& bcm_device_list_lock );
190
+ if (bcm_device_exists (bcm -> dev ))
191
+ bcm_gpio_set_power (bcm -> dev , false);
192
+ spin_unlock (& bcm_device_list_lock );
193
+
111
194
skb_queue_purge (& bcm -> txq );
112
195
kfree_skb (bcm -> rx_skb );
113
196
kfree (bcm );
@@ -232,6 +315,113 @@ static struct sk_buff *bcm_dequeue(struct hci_uart *hu)
232
315
return skb_dequeue (& bcm -> txq );
233
316
}
234
317
318
+ static const struct acpi_gpio_params device_wakeup_gpios = { 0 , 0 , false };
319
+ static const struct acpi_gpio_params shutdown_gpios = { 1 , 0 , false };
320
+
321
+ static const struct acpi_gpio_mapping acpi_bcm_default_gpios [] = {
322
+ { "device-wakeup-gpios" , & device_wakeup_gpios , 1 },
323
+ { "shutdown-gpios" , & shutdown_gpios , 1 },
324
+ { },
325
+ };
326
+
327
+ static int bcm_acpi_probe (struct bcm_device * dev )
328
+ {
329
+ struct platform_device * pdev = dev -> pdev ;
330
+ const struct acpi_device_id * id ;
331
+ struct gpio_desc * gpio ;
332
+ int ret ;
333
+
334
+ id = acpi_match_device (pdev -> dev .driver -> acpi_match_table , & pdev -> dev );
335
+ if (!id )
336
+ return - ENODEV ;
337
+
338
+ /* Retrieve GPIO data */
339
+ dev -> name = dev_name (& pdev -> dev );
340
+ ret = acpi_dev_add_driver_gpios (ACPI_COMPANION (& pdev -> dev ),
341
+ acpi_bcm_default_gpios );
342
+ if (ret )
343
+ return ret ;
344
+
345
+ dev -> clk = devm_clk_get (& pdev -> dev , NULL );
346
+
347
+ gpio = devm_gpiod_get (& pdev -> dev , "device-wakeup" );
348
+ if (!IS_ERR (gpio )) {
349
+ ret = gpiod_direction_output (gpio , 0 );
350
+ if (ret )
351
+ return ret ;
352
+ dev -> device_wakeup = gpio ;
353
+ }
354
+
355
+ gpio = devm_gpiod_get (& pdev -> dev , "shutdown" );
356
+ if (!IS_ERR (gpio )) {
357
+ ret = gpiod_direction_output (gpio , 0 );
358
+ if (ret )
359
+ return ret ;
360
+ dev -> shutdown = gpio ;
361
+ }
362
+
363
+ /* Make sure at-least one of the GPIO is defined and that
364
+ * a name is specified for this instance
365
+ */
366
+ if ((!dev -> device_wakeup && !dev -> shutdown ) || !dev -> name ) {
367
+ dev_err (& pdev -> dev , "invalid platform data\n" );
368
+ return - EINVAL ;
369
+ }
370
+
371
+ return 0 ;
372
+ }
373
+
374
+ static int bcm_probe (struct platform_device * pdev )
375
+ {
376
+ struct bcm_device * dev ;
377
+ struct acpi_device_id * pdata = pdev -> dev .platform_data ;
378
+ int ret ;
379
+
380
+ dev = devm_kzalloc (& pdev -> dev , sizeof (* dev ), GFP_KERNEL );
381
+ if (!dev )
382
+ return - ENOMEM ;
383
+
384
+ dev -> pdev = pdev ;
385
+
386
+ if (ACPI_HANDLE (& pdev -> dev )) {
387
+ ret = bcm_acpi_probe (dev );
388
+ if (ret )
389
+ return ret ;
390
+ } else if (pdata ) {
391
+ dev -> name = pdata -> id ;
392
+ } else {
393
+ return - ENODEV ;
394
+ }
395
+
396
+ platform_set_drvdata (pdev , dev );
397
+
398
+ dev_info (& pdev -> dev , "%s device registered.\n" , dev -> name );
399
+
400
+ /* Place this instance on the device list */
401
+ spin_lock (& bcm_device_list_lock );
402
+ list_add_tail (& dev -> list , & bcm_device_list );
403
+ spin_unlock (& bcm_device_list_lock );
404
+
405
+ bcm_gpio_set_power (dev , false);
406
+
407
+ return 0 ;
408
+ }
409
+
410
+ static int bcm_remove (struct platform_device * pdev )
411
+ {
412
+ struct bcm_device * dev = platform_get_drvdata (pdev );
413
+
414
+ spin_lock (& bcm_device_list_lock );
415
+ list_del (& dev -> list );
416
+ spin_unlock (& bcm_device_list_lock );
417
+
418
+ acpi_dev_remove_driver_gpios (ACPI_COMPANION (& pdev -> dev ));
419
+
420
+ dev_info (& pdev -> dev , "%s device unregistered.\n" , dev -> name );
421
+
422
+ return 0 ;
423
+ }
424
+
235
425
static const struct hci_uart_proto bcm_proto = {
236
426
.id = HCI_UART_BCM ,
237
427
.name = "BCM" ,
@@ -247,12 +437,34 @@ static const struct hci_uart_proto bcm_proto = {
247
437
.dequeue = bcm_dequeue ,
248
438
};
249
439
440
+ #ifdef CONFIG_ACPI
441
+ static const struct acpi_device_id bcm_acpi_match [] = {
442
+ { "BCM2E39" , 0 },
443
+ { "BCM2E67" , 0 },
444
+ { },
445
+ };
446
+ MODULE_DEVICE_TABLE (acpi , bcm_acpi_match );
447
+ #endif
448
+
449
+ static struct platform_driver bcm_driver = {
450
+ .probe = bcm_probe ,
451
+ .remove = bcm_remove ,
452
+ .driver = {
453
+ .name = "hci_bcm" ,
454
+ .acpi_match_table = ACPI_PTR (bcm_acpi_match ),
455
+ },
456
+ };
457
+
250
458
int __init bcm_init (void )
251
459
{
460
+ platform_driver_register (& bcm_driver );
461
+
252
462
return hci_uart_register_proto (& bcm_proto );
253
463
}
254
464
255
465
int __exit bcm_deinit (void )
256
466
{
467
+ platform_driver_unregister (& bcm_driver );
468
+
257
469
return hci_uart_unregister_proto (& bcm_proto );
258
470
}
0 commit comments