5252
5353#define BCM_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */
5454
55- /* platform device driver resources */
55+ /* device driver resources */
5656struct bcm_device {
57+ /* Must be the first member, hci_serdev.c expects this. */
58+ struct hci_uart serdev_hu ;
5759 struct list_head list ;
5860
5961 struct device * dev ;
@@ -76,11 +78,6 @@ struct bcm_device {
7678#endif
7779};
7880
79- /* serdev driver resources */
80- struct bcm_serdev {
81- struct hci_uart hu ;
82- };
83-
8481/* generic bcm uart resources */
8582struct bcm_data {
8683 struct sk_buff * rx_skb ;
@@ -155,6 +152,10 @@ static bool bcm_device_exists(struct bcm_device *device)
155152{
156153 struct list_head * p ;
157154
155+ /* Devices using serdev always exist */
156+ if (device && device -> hu && device -> hu -> serdev )
157+ return true;
158+
158159 list_for_each (p , & bcm_device_list ) {
159160 struct bcm_device * dev = list_entry (p , struct bcm_device , list );
160161
@@ -200,7 +201,6 @@ static int bcm_request_irq(struct bcm_data *bcm)
200201 struct bcm_device * bdev = bcm -> dev ;
201202 int err ;
202203
203- /* If this is not a platform device, do not enable PM functionalities */
204204 mutex_lock (& bcm_device_lock );
205205 if (!bcm_device_exists (bdev )) {
206206 err = - ENODEV ;
@@ -313,18 +313,17 @@ static int bcm_open(struct hci_uart *hu)
313313
314314 hu -> priv = bcm ;
315315
316- /* If this is a serdev defined device, then only use
317- * serdev open primitive and skip the rest.
318- */
316+ mutex_lock (& bcm_device_lock );
317+
319318 if (hu -> serdev ) {
320319 serdev_device_open (hu -> serdev );
320+ bcm -> dev = serdev_device_get_drvdata (hu -> serdev );
321321 goto out ;
322322 }
323323
324324 if (!hu -> tty -> dev )
325325 goto out ;
326326
327- mutex_lock (& bcm_device_lock );
328327 list_for_each (p , & bcm_device_list ) {
329328 struct bcm_device * dev = list_entry (p , struct bcm_device , list );
330329
@@ -334,37 +333,45 @@ static int bcm_open(struct hci_uart *hu)
334333 */
335334 if (hu -> tty -> dev -> parent == dev -> dev -> parent ) {
336335 bcm -> dev = dev ;
337- hu -> init_speed = dev -> init_speed ;
338- hu -> oper_speed = dev -> oper_speed ;
339336#ifdef CONFIG_PM
340337 dev -> hu = hu ;
341338#endif
342- bcm_gpio_set_power (bcm -> dev , true);
343339 break ;
344340 }
345341 }
346342
347- mutex_unlock (& bcm_device_lock );
348343out :
344+ if (bcm -> dev ) {
345+ hu -> init_speed = bcm -> dev -> init_speed ;
346+ hu -> oper_speed = bcm -> dev -> oper_speed ;
347+ bcm_gpio_set_power (bcm -> dev , true);
348+ }
349+
350+ mutex_unlock (& bcm_device_lock );
349351 return 0 ;
350352}
351353
352354static int bcm_close (struct hci_uart * hu )
353355{
354356 struct bcm_data * bcm = hu -> priv ;
355- struct bcm_device * bdev = bcm -> dev ;
357+ struct bcm_device * bdev = NULL ;
356358
357359 bt_dev_dbg (hu -> hdev , "hu %p" , hu );
358360
359- /* If this is a serdev defined device, only use serdev
360- * close primitive and then continue as usual.
361- */
362- if (hu -> serdev )
363- serdev_device_close (hu -> serdev );
364-
365361 /* Protect bcm->dev against removal of the device or driver */
366362 mutex_lock (& bcm_device_lock );
367- if (bcm_device_exists (bdev )) {
363+
364+ if (hu -> serdev ) {
365+ serdev_device_close (hu -> serdev );
366+ bdev = serdev_device_get_drvdata (hu -> serdev );
367+ } else if (bcm_device_exists (bcm -> dev )) {
368+ bdev = bcm -> dev ;
369+ #ifdef CONFIG_PM
370+ bdev -> hu = NULL ;
371+ #endif
372+ }
373+
374+ if (bdev ) {
368375 bcm_gpio_set_power (bdev , false);
369376#ifdef CONFIG_PM
370377 pm_runtime_disable (bdev -> dev );
@@ -374,8 +381,6 @@ static int bcm_close(struct hci_uart *hu)
374381 devm_free_irq (bdev -> dev , bdev -> irq , bdev );
375382 device_init_wakeup (bdev -> dev , false);
376383 }
377-
378- bdev -> hu = NULL ;
379384#endif
380385 }
381386 mutex_unlock (& bcm_device_lock );
@@ -603,16 +608,18 @@ static int bcm_resume_device(struct device *dev)
603608#endif
604609
605610#ifdef CONFIG_PM_SLEEP
606- /* Platform suspend callback */
611+ /* suspend callback */
607612static int bcm_suspend (struct device * dev )
608613{
609614 struct bcm_device * bdev = dev_get_drvdata (dev );
610615 int error ;
611616
612617 bt_dev_dbg (bdev , "suspend: is_suspended %d" , bdev -> is_suspended );
613618
614- /* bcm_suspend can be called at any time as long as platform device is
615- * bound, so it should use bcm_device_lock to protect access to hci_uart
619+ /*
620+ * When used with a device instantiated as platform_device, bcm_suspend
621+ * can be called at any time as long as the platform device is bound,
622+ * so it should use bcm_device_lock to protect access to hci_uart
616623 * and device_wake-up GPIO.
617624 */
618625 mutex_lock (& bcm_device_lock );
@@ -635,15 +642,17 @@ static int bcm_suspend(struct device *dev)
635642 return 0 ;
636643}
637644
638- /* Platform resume callback */
645+ /* resume callback */
639646static int bcm_resume (struct device * dev )
640647{
641648 struct bcm_device * bdev = dev_get_drvdata (dev );
642649
643650 bt_dev_dbg (bdev , "resume: is_suspended %d" , bdev -> is_suspended );
644651
645- /* bcm_resume can be called at any time as long as platform device is
646- * bound, so it should use bcm_device_lock to protect access to hci_uart
652+ /*
653+ * When used with a device instantiated as platform_device, bcm_resume
654+ * can be called at any time as long as platform device is bound,
655+ * so it should use bcm_device_lock to protect access to hci_uart
647656 * and device_wake-up GPIO.
648657 */
649658 mutex_lock (& bcm_device_lock );
@@ -785,15 +794,6 @@ static int bcm_get_resources(struct bcm_device *dev)
785794 }
786795
787796 dev_info (dev -> dev , "BCM irq: %d\n" , dev -> irq );
788-
789- /* Make sure at-least one of the GPIO is defined and that
790- * a name is specified for this instance
791- */
792- if ((!dev -> device_wakeup && !dev -> shutdown ) || !dev -> name ) {
793- dev_err (dev -> dev , "invalid platform data\n" );
794- return - EINVAL ;
795- }
796-
797797 return 0 ;
798798}
799799
@@ -846,6 +846,12 @@ static int bcm_acpi_probe(struct bcm_device *dev)
846846}
847847#endif /* CONFIG_ACPI */
848848
849+ static int bcm_of_probe (struct bcm_device * bdev )
850+ {
851+ device_property_read_u32 (bdev -> dev , "max-speed" , & bdev -> oper_speed );
852+ return 0 ;
853+ }
854+
849855static int bcm_probe (struct platform_device * pdev )
850856{
851857 struct bcm_device * dev ;
@@ -933,7 +939,7 @@ static const struct acpi_device_id bcm_acpi_match[] = {
933939MODULE_DEVICE_TABLE (acpi , bcm_acpi_match );
934940#endif
935941
936- /* Platform suspend and resume callbacks */
942+ /* suspend and resume callbacks */
937943static const struct dev_pm_ops bcm_pm_ops = {
938944 SET_SYSTEM_SLEEP_PM_OPS (bcm_suspend , bcm_resume )
939945 SET_RUNTIME_PM_OPS (bcm_suspend_device , bcm_resume_device , NULL )
@@ -951,29 +957,39 @@ static struct platform_driver bcm_driver = {
951957
952958static int bcm_serdev_probe (struct serdev_device * serdev )
953959{
954- struct bcm_serdev * bcmdev ;
955- u32 speed ;
960+ struct bcm_device * bcmdev ;
956961 int err ;
957962
958963 bcmdev = devm_kzalloc (& serdev -> dev , sizeof (* bcmdev ), GFP_KERNEL );
959964 if (!bcmdev )
960965 return - ENOMEM ;
961966
962- bcmdev -> hu .serdev = serdev ;
967+ bcmdev -> dev = & serdev -> dev ;
968+ bcmdev -> hu = & bcmdev -> serdev_hu ;
969+ bcmdev -> serdev_hu .serdev = serdev ;
963970 serdev_device_set_drvdata (serdev , bcmdev );
964971
965- err = device_property_read_u32 (& serdev -> dev , "max-speed" , & speed );
966- if (!err )
967- bcmdev -> hu .oper_speed = speed ;
972+ if (has_acpi_companion (& serdev -> dev ))
973+ err = bcm_acpi_probe (bcmdev );
974+ else
975+ err = bcm_of_probe (bcmdev );
976+ if (err )
977+ return err ;
968978
969- return hci_uart_register_device (& bcmdev -> hu , & bcm_proto );
979+ err = bcm_get_resources (bcmdev );
980+ if (err )
981+ return err ;
982+
983+ bcm_gpio_set_power (bcmdev , false);
984+
985+ return hci_uart_register_device (& bcmdev -> serdev_hu , & bcm_proto );
970986}
971987
972988static void bcm_serdev_remove (struct serdev_device * serdev )
973989{
974- struct bcm_serdev * bcmdev = serdev_device_get_drvdata (serdev );
990+ struct bcm_device * bcmdev = serdev_device_get_drvdata (serdev );
975991
976- hci_uart_unregister_device (& bcmdev -> hu );
992+ hci_uart_unregister_device (& bcmdev -> serdev_hu );
977993}
978994
979995#ifdef CONFIG_OF
@@ -990,6 +1006,8 @@ static struct serdev_device_driver bcm_serdev_driver = {
9901006 .driver = {
9911007 .name = "hci_uart_bcm" ,
9921008 .of_match_table = of_match_ptr (bcm_bluetooth_of_match ),
1009+ .acpi_match_table = ACPI_PTR (bcm_acpi_match ),
1010+ .pm = & bcm_pm_ops ,
9931011 },
9941012};
9951013
0 commit comments