2015-04-05 02:13:02 +03:00
/*
*
* Bluetooth HCI UART driver for Intel devices
*
* Copyright ( C ) 2015 Intel Corporation
*
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/skbuff.h>
2015-07-01 13:20:26 +03:00
# include <linux/firmware.h>
2015-08-27 08:21:51 +03:00
# include <linux/module.h>
2015-07-01 13:20:26 +03:00
# include <linux/wait.h>
2015-08-27 08:21:51 +03:00
# include <linux/tty.h>
# include <linux/platform_device.h>
# include <linux/gpio/consumer.h>
# include <linux/acpi.h>
2015-08-29 14:38:18 +03:00
# include <linux/interrupt.h>
2015-09-02 13:04:13 +03:00
# include <linux/pm_runtime.h>
2015-04-05 02:13:02 +03:00
# include <net/bluetooth/bluetooth.h>
# include <net/bluetooth/hci_core.h>
# include "hci_uart.h"
2015-07-01 13:20:26 +03:00
# include "btintel.h"
# define STATE_BOOTLOADER 0
# define STATE_DOWNLOADING 1
# define STATE_FIRMWARE_LOADED 2
# define STATE_FIRMWARE_FAILED 3
# define STATE_BOOTING 4
2015-08-29 14:38:19 +03:00
# define STATE_LPM_ENABLED 5
# define STATE_TX_ACTIVE 6
2015-09-02 13:04:11 +03:00
# define STATE_SUSPENDED 7
# define STATE_LPM_TRANSACTION 8
2015-08-29 14:38:19 +03:00
2015-09-02 13:04:11 +03:00
# define HCI_LPM_WAKE_PKT 0xf0
2015-08-29 14:38:19 +03:00
# define HCI_LPM_PKT 0xf1
# define HCI_LPM_MAX_SIZE 10
# define HCI_LPM_HDR_SIZE HCI_EVENT_HDR_SIZE
# define LPM_OP_TX_NOTIFY 0x00
2015-09-02 13:04:11 +03:00
# define LPM_OP_SUSPEND_ACK 0x02
# define LPM_OP_RESUME_ACK 0x03
2015-08-29 14:38:19 +03:00
2015-09-02 13:04:13 +03:00
# define LPM_SUSPEND_DELAY_MS 1000
2015-08-29 14:38:19 +03:00
struct hci_lpm_pkt {
__u8 opcode ;
__u8 dlen ;
__u8 data [ 0 ] ;
} __packed ;
2015-07-01 13:20:26 +03:00
2015-08-27 08:21:51 +03:00
struct intel_device {
struct list_head list ;
struct platform_device * pdev ;
struct gpio_desc * reset ;
2015-09-02 13:04:12 +03:00
struct hci_uart * hu ;
struct mutex hu_lock ;
2015-08-29 14:38:18 +03:00
int irq ;
2015-08-27 08:21:51 +03:00
} ;
static LIST_HEAD ( intel_device_list ) ;
2015-08-31 19:34:31 +03:00
static DEFINE_MUTEX ( intel_device_list_lock ) ;
2015-08-27 08:21:51 +03:00
2015-07-01 13:20:26 +03:00
struct intel_data {
struct sk_buff * rx_skb ;
struct sk_buff_head txq ;
2015-09-02 13:04:13 +03:00
struct work_struct busy_work ;
struct hci_uart * hu ;
2015-07-01 13:20:26 +03:00
unsigned long flags ;
} ;
2015-08-25 18:55:44 +03:00
static u8 intel_convert_speed ( unsigned int speed )
{
switch ( speed ) {
case 9600 :
return 0x00 ;
case 19200 :
return 0x01 ;
case 38400 :
return 0x02 ;
case 57600 :
return 0x03 ;
case 115200 :
return 0x04 ;
case 230400 :
return 0x05 ;
case 460800 :
return 0x06 ;
case 921600 :
return 0x07 ;
case 1843200 :
return 0x08 ;
case 3250000 :
return 0x09 ;
case 2000000 :
return 0x0a ;
case 3000000 :
return 0x0b ;
default :
return 0xff ;
}
}
2015-08-27 08:21:51 +03:00
static int intel_wait_booting ( struct hci_uart * hu )
{
struct intel_data * intel = hu - > priv ;
int err ;
err = wait_on_bit_timeout ( & intel - > flags , STATE_BOOTING ,
TASK_INTERRUPTIBLE ,
msecs_to_jiffies ( 1000 ) ) ;
if ( err = = 1 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hu - > hdev , " Device boot interrupted " ) ;
2015-08-27 08:21:51 +03:00
return - EINTR ;
}
if ( err ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hu - > hdev , " Device boot timeout " ) ;
2015-08-27 08:21:51 +03:00
return - ETIMEDOUT ;
}
return err ;
}
2015-09-04 18:39:25 +03:00
# ifdef CONFIG_PM
2015-09-02 13:04:11 +03:00
static int intel_wait_lpm_transaction ( struct hci_uart * hu )
{
struct intel_data * intel = hu - > priv ;
int err ;
err = wait_on_bit_timeout ( & intel - > flags , STATE_LPM_TRANSACTION ,
TASK_INTERRUPTIBLE ,
msecs_to_jiffies ( 1000 ) ) ;
if ( err = = 1 ) {
bt_dev_err ( hu - > hdev , " LPM transaction interrupted " ) ;
return - EINTR ;
}
if ( err ) {
bt_dev_err ( hu - > hdev , " LPM transaction timeout " ) ;
return - ETIMEDOUT ;
}
return err ;
}
static int intel_lpm_suspend ( struct hci_uart * hu )
{
static const u8 suspend [ ] = { 0x01 , 0x01 , 0x01 } ;
struct intel_data * intel = hu - > priv ;
struct sk_buff * skb ;
if ( ! test_bit ( STATE_LPM_ENABLED , & intel - > flags ) | |
test_bit ( STATE_SUSPENDED , & intel - > flags ) )
return 0 ;
if ( test_bit ( STATE_TX_ACTIVE , & intel - > flags ) )
return - EAGAIN ;
bt_dev_dbg ( hu - > hdev , " Suspending " ) ;
skb = bt_skb_alloc ( sizeof ( suspend ) , GFP_KERNEL ) ;
if ( ! skb ) {
bt_dev_err ( hu - > hdev , " Failed to alloc memory for LPM packet " ) ;
return - ENOMEM ;
}
memcpy ( skb_put ( skb , sizeof ( suspend ) ) , suspend , sizeof ( suspend ) ) ;
bt_cb ( skb ) - > pkt_type = HCI_LPM_PKT ;
set_bit ( STATE_LPM_TRANSACTION , & intel - > flags ) ;
skb_queue_tail ( & intel - > txq , skb ) ;
hci_uart_tx_wakeup ( hu ) ;
intel_wait_lpm_transaction ( hu ) ;
/* Even in case of failure, continue and test the suspended flag */
clear_bit ( STATE_LPM_TRANSACTION , & intel - > flags ) ;
if ( ! test_bit ( STATE_SUSPENDED , & intel - > flags ) ) {
bt_dev_err ( hu - > hdev , " Device suspend error " ) ;
return - EINVAL ;
}
bt_dev_dbg ( hu - > hdev , " Suspended " ) ;
hci_uart_set_flow_control ( hu , true ) ;
return 0 ;
}
static int intel_lpm_resume ( struct hci_uart * hu )
{
struct intel_data * intel = hu - > priv ;
struct sk_buff * skb ;
if ( ! test_bit ( STATE_LPM_ENABLED , & intel - > flags ) | |
! test_bit ( STATE_SUSPENDED , & intel - > flags ) )
return 0 ;
bt_dev_dbg ( hu - > hdev , " Resuming " ) ;
hci_uart_set_flow_control ( hu , false ) ;
skb = bt_skb_alloc ( 0 , GFP_KERNEL ) ;
if ( ! skb ) {
bt_dev_err ( hu - > hdev , " Failed to alloc memory for LPM packet " ) ;
return - ENOMEM ;
}
bt_cb ( skb ) - > pkt_type = HCI_LPM_WAKE_PKT ;
set_bit ( STATE_LPM_TRANSACTION , & intel - > flags ) ;
skb_queue_tail ( & intel - > txq , skb ) ;
hci_uart_tx_wakeup ( hu ) ;
intel_wait_lpm_transaction ( hu ) ;
/* Even in case of failure, continue and test the suspended flag */
clear_bit ( STATE_LPM_TRANSACTION , & intel - > flags ) ;
if ( test_bit ( STATE_SUSPENDED , & intel - > flags ) ) {
bt_dev_err ( hu - > hdev , " Device resume error " ) ;
return - EINVAL ;
}
bt_dev_dbg ( hu - > hdev , " Resumed " ) ;
return 0 ;
}
2015-09-04 18:39:25 +03:00
# endif /* CONFIG_PM */
2015-09-02 13:04:11 +03:00
static int intel_lpm_host_wake ( struct hci_uart * hu )
{
static const u8 lpm_resume_ack [ ] = { LPM_OP_RESUME_ACK , 0x00 } ;
struct intel_data * intel = hu - > priv ;
struct sk_buff * skb ;
hci_uart_set_flow_control ( hu , false ) ;
clear_bit ( STATE_SUSPENDED , & intel - > flags ) ;
skb = bt_skb_alloc ( sizeof ( lpm_resume_ack ) , GFP_KERNEL ) ;
if ( ! skb ) {
bt_dev_err ( hu - > hdev , " Failed to alloc memory for LPM packet " ) ;
return - ENOMEM ;
}
memcpy ( skb_put ( skb , sizeof ( lpm_resume_ack ) ) , lpm_resume_ack ,
sizeof ( lpm_resume_ack ) ) ;
bt_cb ( skb ) - > pkt_type = HCI_LPM_PKT ;
skb_queue_tail ( & intel - > txq , skb ) ;
hci_uart_tx_wakeup ( hu ) ;
bt_dev_dbg ( hu - > hdev , " Resumed by controller " ) ;
return 0 ;
}
2015-08-29 14:38:18 +03:00
static irqreturn_t intel_irq ( int irq , void * dev_id )
{
struct intel_device * idev = dev_id ;
dev_info ( & idev - > pdev - > dev , " hci_intel irq \n " ) ;
2015-09-02 13:04:12 +03:00
mutex_lock ( & idev - > hu_lock ) ;
if ( idev - > hu )
intel_lpm_host_wake ( idev - > hu ) ;
mutex_unlock ( & idev - > hu_lock ) ;
2015-09-02 13:04:13 +03:00
/* Host/Controller are now LPM resumed, trigger a new delayed suspend */
pm_runtime_get ( & idev - > pdev - > dev ) ;
pm_runtime_mark_last_busy ( & idev - > pdev - > dev ) ;
pm_runtime_put_autosuspend ( & idev - > pdev - > dev ) ;
2015-08-29 14:38:18 +03:00
return IRQ_HANDLED ;
}
2015-08-27 08:21:51 +03:00
static int intel_set_power ( struct hci_uart * hu , bool powered )
{
struct list_head * p ;
int err = - ENODEV ;
2015-08-31 19:34:31 +03:00
mutex_lock ( & intel_device_list_lock ) ;
2015-08-27 08:21:51 +03:00
list_for_each ( p , & intel_device_list ) {
struct intel_device * idev = list_entry ( p , struct intel_device ,
list ) ;
/* tty device and pdev device should share the same parent
* which is the UART port .
*/
if ( hu - > tty - > dev - > parent ! = idev - > pdev - > dev . parent )
continue ;
if ( ! idev - > reset ) {
err = - ENOTSUPP ;
break ;
}
BT_INFO ( " hu %p, Switching compatible pm device (%s) to %u " ,
hu , dev_name ( & idev - > pdev - > dev ) , powered ) ;
gpiod_set_value ( idev - > reset , powered ) ;
2015-08-29 14:38:18 +03:00
2015-09-02 13:04:12 +03:00
/* Provide to idev a hu reference which is used to run LPM
* transactions ( lpm suspend / resume ) from PM callbacks .
* hu needs to be protected against concurrent removing during
* these PM ops .
*/
mutex_lock ( & idev - > hu_lock ) ;
idev - > hu = powered ? hu : NULL ;
mutex_unlock ( & idev - > hu_lock ) ;
2015-08-29 14:38:18 +03:00
if ( idev - > irq < 0 )
break ;
if ( powered & & device_can_wakeup ( & idev - > pdev - > dev ) ) {
err = devm_request_threaded_irq ( & idev - > pdev - > dev ,
idev - > irq , NULL ,
intel_irq ,
IRQF_ONESHOT ,
" bt-host-wake " , idev ) ;
if ( err ) {
BT_ERR ( " hu %p, unable to allocate irq-%d " ,
hu , idev - > irq ) ;
break ;
}
device_wakeup_enable ( & idev - > pdev - > dev ) ;
2015-09-02 13:04:13 +03:00
pm_runtime_set_active ( & idev - > pdev - > dev ) ;
pm_runtime_use_autosuspend ( & idev - > pdev - > dev ) ;
pm_runtime_set_autosuspend_delay ( & idev - > pdev - > dev ,
LPM_SUSPEND_DELAY_MS ) ;
pm_runtime_enable ( & idev - > pdev - > dev ) ;
2015-08-29 14:38:18 +03:00
} else if ( ! powered & & device_may_wakeup ( & idev - > pdev - > dev ) ) {
devm_free_irq ( & idev - > pdev - > dev , idev - > irq , idev ) ;
device_wakeup_disable ( & idev - > pdev - > dev ) ;
2015-09-02 13:04:13 +03:00
pm_runtime_disable ( & idev - > pdev - > dev ) ;
2015-08-29 14:38:18 +03:00
}
2015-08-27 08:21:51 +03:00
}
2015-08-31 19:34:31 +03:00
mutex_unlock ( & intel_device_list_lock ) ;
2015-08-27 08:21:51 +03:00
return err ;
}
2015-09-02 13:04:13 +03:00
static void intel_busy_work ( struct work_struct * work )
{
struct list_head * p ;
struct intel_data * intel = container_of ( work , struct intel_data ,
busy_work ) ;
/* Link is busy, delay the suspend */
mutex_lock ( & intel_device_list_lock ) ;
list_for_each ( p , & intel_device_list ) {
struct intel_device * idev = list_entry ( p , struct intel_device ,
list ) ;
if ( intel - > hu - > tty - > dev - > parent = = idev - > pdev - > dev . parent ) {
pm_runtime_get ( & idev - > pdev - > dev ) ;
pm_runtime_mark_last_busy ( & idev - > pdev - > dev ) ;
pm_runtime_put_autosuspend ( & idev - > pdev - > dev ) ;
break ;
}
}
mutex_unlock ( & intel_device_list_lock ) ;
}
2015-07-01 13:20:26 +03:00
static int intel_open ( struct hci_uart * hu )
{
struct intel_data * intel ;
BT_DBG ( " hu %p " , hu ) ;
intel = kzalloc ( sizeof ( * intel ) , GFP_KERNEL ) ;
if ( ! intel )
return - ENOMEM ;
skb_queue_head_init ( & intel - > txq ) ;
2015-09-02 13:04:13 +03:00
INIT_WORK ( & intel - > busy_work , intel_busy_work ) ;
intel - > hu = hu ;
2015-07-01 13:20:26 +03:00
hu - > priv = intel ;
2015-08-27 08:21:51 +03:00
if ( ! intel_set_power ( hu , true ) )
set_bit ( STATE_BOOTING , & intel - > flags ) ;
2015-07-01 13:20:26 +03:00
return 0 ;
}
static int intel_close ( struct hci_uart * hu )
{
struct intel_data * intel = hu - > priv ;
BT_DBG ( " hu %p " , hu ) ;
2015-09-02 13:04:13 +03:00
cancel_work_sync ( & intel - > busy_work ) ;
2015-08-27 08:21:51 +03:00
intel_set_power ( hu , false ) ;
2015-07-01 13:20:26 +03:00
skb_queue_purge ( & intel - > txq ) ;
kfree_skb ( intel - > rx_skb ) ;
kfree ( intel ) ;
hu - > priv = NULL ;
return 0 ;
}
static int intel_flush ( struct hci_uart * hu )
{
struct intel_data * intel = hu - > priv ;
BT_DBG ( " hu %p " , hu ) ;
skb_queue_purge ( & intel - > txq ) ;
return 0 ;
}
static int inject_cmd_complete ( struct hci_dev * hdev , __u16 opcode )
{
struct sk_buff * skb ;
struct hci_event_hdr * hdr ;
struct hci_ev_cmd_complete * evt ;
skb = bt_skb_alloc ( sizeof ( * hdr ) + sizeof ( * evt ) + 1 , GFP_ATOMIC ) ;
if ( ! skb )
return - ENOMEM ;
hdr = ( struct hci_event_hdr * ) skb_put ( skb , sizeof ( * hdr ) ) ;
hdr - > evt = HCI_EV_CMD_COMPLETE ;
hdr - > plen = sizeof ( * evt ) + 1 ;
evt = ( struct hci_ev_cmd_complete * ) skb_put ( skb , sizeof ( * evt ) ) ;
evt - > ncmd = 0x01 ;
evt - > opcode = cpu_to_le16 ( opcode ) ;
* skb_put ( skb , 1 ) = 0x00 ;
bt_cb ( skb ) - > pkt_type = HCI_EVENT_PKT ;
return hci_recv_frame ( hdev , skb ) ;
}
2015-08-25 18:55:44 +03:00
static int intel_set_baudrate ( struct hci_uart * hu , unsigned int speed )
{
struct intel_data * intel = hu - > priv ;
struct hci_dev * hdev = hu - > hdev ;
u8 speed_cmd [ ] = { 0x06 , 0xfc , 0x01 , 0x00 } ;
struct sk_buff * skb ;
2015-08-27 08:21:51 +03:00
int err ;
/* This can be the first command sent to the chip, check
* that the controller is ready .
*/
err = intel_wait_booting ( hu ) ;
clear_bit ( STATE_BOOTING , & intel - > flags ) ;
/* In case of timeout, try to continue anyway */
if ( err & & err ! = ETIMEDOUT )
return err ;
2015-08-25 18:55:44 +03:00
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Change controller speed to %d " , speed ) ;
2015-08-25 18:55:44 +03:00
speed_cmd [ 3 ] = intel_convert_speed ( speed ) ;
if ( speed_cmd [ 3 ] = = 0xff ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Unsupported speed " ) ;
2015-08-25 18:55:44 +03:00
return - EINVAL ;
}
/* Device will not accept speed change if Intel version has not been
* previously requested .
*/
skb = __hci_cmd_sync ( hdev , 0xfc05 , 0 , NULL , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Reading Intel version information failed (%ld) " ,
PTR_ERR ( skb ) ) ;
2015-08-25 18:55:44 +03:00
return PTR_ERR ( skb ) ;
}
kfree_skb ( skb ) ;
skb = bt_skb_alloc ( sizeof ( speed_cmd ) , GFP_KERNEL ) ;
if ( ! skb ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Failed to alloc memory for baudrate packet " ) ;
2015-08-25 18:55:44 +03:00
return - ENOMEM ;
}
memcpy ( skb_put ( skb , sizeof ( speed_cmd ) ) , speed_cmd , sizeof ( speed_cmd ) ) ;
bt_cb ( skb ) - > pkt_type = HCI_COMMAND_PKT ;
hci_uart_set_flow_control ( hu , true ) ;
skb_queue_tail ( & intel - > txq , skb ) ;
hci_uart_tx_wakeup ( hu ) ;
/* wait 100ms to change baudrate on controller side */
msleep ( 100 ) ;
hci_uart_set_baudrate ( hu , speed ) ;
hci_uart_set_flow_control ( hu , false ) ;
return 0 ;
}
2015-07-01 13:20:26 +03:00
static int intel_setup ( struct hci_uart * hu )
{
static const u8 reset_param [ ] = { 0x00 , 0x01 , 0x00 , 0x01 ,
0x00 , 0x08 , 0x04 , 0x00 } ;
2015-08-29 14:38:19 +03:00
static const u8 lpm_param [ ] = { 0x03 , 0x07 , 0x01 , 0x0b } ;
2015-07-01 13:20:26 +03:00
struct intel_data * intel = hu - > priv ;
2015-08-29 14:38:19 +03:00
struct intel_device * idev = NULL ;
2015-07-01 13:20:26 +03:00
struct hci_dev * hdev = hu - > hdev ;
struct sk_buff * skb ;
struct intel_version * ver ;
struct intel_boot_params * params ;
2015-08-29 14:38:19 +03:00
struct list_head * p ;
2015-07-01 13:20:26 +03:00
const struct firmware * fw ;
const u8 * fw_ptr ;
char fwname [ 64 ] ;
u32 frag_len ;
ktime_t calltime , delta , rettime ;
unsigned long long duration ;
2015-08-25 18:55:44 +03:00
unsigned int init_speed , oper_speed ;
int speed_change = 0 ;
2015-07-01 13:20:26 +03:00
int err ;
2015-08-31 19:34:30 +03:00
bt_dev_dbg ( hdev , " start intel_setup " ) ;
2015-07-01 13:20:26 +03:00
2015-07-05 15:37:40 +03:00
hu - > hdev - > set_bdaddr = btintel_set_bdaddr ;
2015-07-01 13:20:26 +03:00
calltime = ktime_get ( ) ;
2015-08-25 18:55:44 +03:00
if ( hu - > init_speed )
init_speed = hu - > init_speed ;
else
init_speed = hu - > proto - > init_speed ;
if ( hu - > oper_speed )
oper_speed = hu - > oper_speed ;
else
oper_speed = hu - > proto - > oper_speed ;
if ( oper_speed & & init_speed & & oper_speed ! = init_speed )
speed_change = 1 ;
2015-08-27 08:21:51 +03:00
/* Check that the controller is ready */
err = intel_wait_booting ( hu ) ;
clear_bit ( STATE_BOOTING , & intel - > flags ) ;
/* In case of timeout, try to continue anyway */
if ( err & & err ! = ETIMEDOUT )
return err ;
2015-07-01 13:20:26 +03:00
set_bit ( STATE_BOOTLOADER , & intel - > flags ) ;
/* Read the Intel version information to determine if the device
* is in bootloader mode or if it already has operational firmware
* loaded .
*/
skb = __hci_cmd_sync ( hdev , 0xfc05 , 0 , NULL , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Reading Intel version information failed (%ld) " ,
PTR_ERR ( skb ) ) ;
2015-07-01 13:20:26 +03:00
return PTR_ERR ( skb ) ;
}
if ( skb - > len ! = sizeof ( * ver ) ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Intel version event size mismatch " ) ;
2015-07-01 13:20:26 +03:00
kfree_skb ( skb ) ;
return - EILSEQ ;
}
ver = ( struct intel_version * ) skb - > data ;
if ( ver - > status ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Intel version command failure (%02x) " ,
ver - > status ) ;
2015-07-01 13:20:26 +03:00
err = - bt_to_errno ( ver - > status ) ;
kfree_skb ( skb ) ;
return err ;
}
/* The hardware platform number has a fixed value of 0x37 and
* for now only accept this single value .
*/
if ( ver - > hw_platform ! = 0x37 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Unsupported Intel hardware platform (%u) " ,
ver - > hw_platform ) ;
2015-07-01 13:20:26 +03:00
kfree_skb ( skb ) ;
return - EINVAL ;
}
/* At the moment only the hardware variant iBT 3.0 (LnP/SfP) is
* supported by this firmware loading method . This check has been
* put in place to ensure correct forward compatibility options
* when newer hardware variants come along .
*/
if ( ver - > hw_variant ! = 0x0b ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Unsupported Intel hardware variant (%u) " ,
ver - > hw_variant ) ;
2015-07-01 13:20:26 +03:00
kfree_skb ( skb ) ;
return - EINVAL ;
}
2015-07-05 16:02:07 +03:00
btintel_version_info ( hdev , ver ) ;
2015-07-01 13:20:26 +03:00
/* The firmware variant determines if the device is in bootloader
* mode or is running operational firmware . The value 0x06 identifies
* the bootloader and the value 0x23 identifies the operational
* firmware .
*
* When the operational firmware is already present , then only
* the check for valid Bluetooth device address is needed . This
* determines if the device will be added as configured or
* unconfigured controller .
*
* It is not possible to use the Secure Boot Parameters in this
* case since that command is only available in bootloader mode .
*/
if ( ver - > fw_variant = = 0x23 ) {
kfree_skb ( skb ) ;
clear_bit ( STATE_BOOTLOADER , & intel - > flags ) ;
btintel_check_bdaddr ( hdev ) ;
return 0 ;
}
/* If the device is not in bootloader mode, then the only possible
* choice is to return an error and abort the device initialization .
*/
if ( ver - > fw_variant ! = 0x06 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Unsupported Intel firmware variant (%u) " ,
ver - > fw_variant ) ;
2015-07-01 13:20:26 +03:00
kfree_skb ( skb ) ;
return - ENODEV ;
}
kfree_skb ( skb ) ;
/* Read the secure boot parameters to identify the operating
* details of the bootloader .
*/
skb = __hci_cmd_sync ( hdev , 0xfc0d , 0 , NULL , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Reading Intel boot parameters failed (%ld) " ,
PTR_ERR ( skb ) ) ;
2015-07-01 13:20:26 +03:00
return PTR_ERR ( skb ) ;
}
if ( skb - > len ! = sizeof ( * params ) ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Intel boot parameters size mismatch " ) ;
2015-07-01 13:20:26 +03:00
kfree_skb ( skb ) ;
return - EILSEQ ;
}
params = ( struct intel_boot_params * ) skb - > data ;
if ( params - > status ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Intel boot parameters command failure (%02x) " ,
params - > status ) ;
2015-07-01 13:20:26 +03:00
err = - bt_to_errno ( params - > status ) ;
kfree_skb ( skb ) ;
return err ;
}
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Device revision is %u " ,
le16_to_cpu ( params - > dev_revid ) ) ;
2015-07-01 13:20:26 +03:00
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Secure boot is %s " ,
params - > secure_boot ? " enabled " : " disabled " ) ;
2015-07-01 13:20:26 +03:00
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Minimum firmware build %u week %u %u " ,
2015-07-01 13:20:26 +03:00
params - > min_fw_build_nn , params - > min_fw_build_cw ,
2000 + params - > min_fw_build_yy ) ;
/* It is required that every single firmware fragment is acknowledged
* with a command complete event . If the boot parameters indicate
* that this bootloader does not send them , then abort the setup .
*/
if ( params - > limited_cce ! = 0x00 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Unsupported Intel firmware loading method (%u) " ,
params - > limited_cce ) ;
2015-07-01 13:20:26 +03:00
kfree_skb ( skb ) ;
return - EINVAL ;
}
/* If the OTP has no valid Bluetooth device address, then there will
* also be no valid address for the operational firmware .
*/
if ( ! bacmp ( & params - > otp_bdaddr , BDADDR_ANY ) ) {
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " No device address configured " ) ;
2015-07-01 13:20:26 +03:00
set_bit ( HCI_QUIRK_INVALID_BDADDR , & hdev - > quirks ) ;
}
/* With this Intel bootloader only the hardware variant and device
* revision information are used to select the right firmware .
*
* Currently this bootloader support is limited to hardware variant
* iBT 3.0 ( LnP / SfP ) which is identified by the value 11 ( 0x0b ) .
*/
snprintf ( fwname , sizeof ( fwname ) , " intel/ibt-11-%u.sfi " ,
le16_to_cpu ( params - > dev_revid ) ) ;
err = request_firmware ( & fw , fwname , & hdev - > dev ) ;
if ( err < 0 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Failed to load Intel firmware file (%d) " ,
err ) ;
2015-07-01 13:20:26 +03:00
kfree_skb ( skb ) ;
return err ;
}
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Found device firmware: %s " , fwname ) ;
2015-07-01 13:20:26 +03:00
2015-09-04 18:54:35 +03:00
/* Save the DDC file name for later */
snprintf ( fwname , sizeof ( fwname ) , " intel/ibt-11-%u.ddc " ,
le16_to_cpu ( params - > dev_revid ) ) ;
2015-07-01 13:20:26 +03:00
kfree_skb ( skb ) ;
if ( fw - > size < 644 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Invalid size of firmware file (%zu) " ,
fw - > size ) ;
2015-07-01 13:20:26 +03:00
err = - EBADF ;
goto done ;
}
set_bit ( STATE_DOWNLOADING , & intel - > flags ) ;
/* Start the firmware download transaction with the Init fragment
* represented by the 128 bytes of CSS header .
*/
2015-07-05 15:55:36 +03:00
err = btintel_secure_send ( hdev , 0x00 , 128 , fw - > data ) ;
2015-07-01 13:20:26 +03:00
if ( err < 0 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Failed to send firmware header (%d) " , err ) ;
2015-07-01 13:20:26 +03:00
goto done ;
}
/* Send the 256 bytes of public key information from the firmware
* as the PKey fragment .
*/
2015-07-05 15:55:36 +03:00
err = btintel_secure_send ( hdev , 0x03 , 256 , fw - > data + 128 ) ;
2015-07-01 13:20:26 +03:00
if ( err < 0 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Failed to send firmware public key (%d) " ,
err ) ;
2015-07-01 13:20:26 +03:00
goto done ;
}
/* Send the 256 bytes of signature information from the firmware
* as the Sign fragment .
*/
2015-07-05 15:55:36 +03:00
err = btintel_secure_send ( hdev , 0x02 , 256 , fw - > data + 388 ) ;
2015-07-01 13:20:26 +03:00
if ( err < 0 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Failed to send firmware signature (%d) " ,
err ) ;
2015-07-01 13:20:26 +03:00
goto done ;
}
fw_ptr = fw - > data + 644 ;
frag_len = 0 ;
while ( fw_ptr - fw - > data < fw - > size ) {
struct hci_command_hdr * cmd = ( void * ) ( fw_ptr + frag_len ) ;
frag_len + = sizeof ( * cmd ) + cmd - > plen ;
2015-08-31 19:34:30 +03:00
bt_dev_dbg ( hdev , " Patching %td/%zu " , ( fw_ptr - fw - > data ) ,
fw - > size ) ;
2015-07-01 13:20:26 +03:00
/* The parameter length of the secure send command requires
* a 4 byte alignment . It happens so that the firmware file
* contains proper Intel_NOP commands to align the fragments
* as needed .
*
* Send set of commands with 4 byte alignment from the
* firmware data buffer as a single Data fragement .
*/
if ( frag_len % 4 )
continue ;
/* Send each command from the firmware data buffer as
* a single Data fragment .
*/
2015-07-05 15:55:36 +03:00
err = btintel_secure_send ( hdev , 0x01 , frag_len , fw_ptr ) ;
2015-07-01 13:20:26 +03:00
if ( err < 0 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Failed to send firmware data (%d) " ,
err ) ;
2015-07-01 13:20:26 +03:00
goto done ;
}
fw_ptr + = frag_len ;
frag_len = 0 ;
}
set_bit ( STATE_FIRMWARE_LOADED , & intel - > flags ) ;
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Waiting for firmware download to complete " ) ;
2015-07-01 13:20:26 +03:00
/* Before switching the device into operational mode and with that
* booting the loaded firmware , wait for the bootloader notification
* that all fragments have been successfully received .
*
* When the event processing receives the notification , then the
* STATE_DOWNLOADING flag will be cleared .
*
* The firmware loading should not take longer than 5 seconds
* and thus just timeout if that happens and fail the setup
* of this device .
*/
err = wait_on_bit_timeout ( & intel - > flags , STATE_DOWNLOADING ,
TASK_INTERRUPTIBLE ,
msecs_to_jiffies ( 5000 ) ) ;
if ( err = = 1 ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Firmware loading interrupted " ) ;
2015-07-01 13:20:26 +03:00
err = - EINTR ;
goto done ;
}
if ( err ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Firmware loading timeout " ) ;
2015-07-01 13:20:26 +03:00
err = - ETIMEDOUT ;
goto done ;
}
if ( test_bit ( STATE_FIRMWARE_FAILED , & intel - > flags ) ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Firmware loading failed " ) ;
2015-07-01 13:20:26 +03:00
err = - ENOEXEC ;
goto done ;
}
rettime = ktime_get ( ) ;
delta = ktime_sub ( rettime , calltime ) ;
duration = ( unsigned long long ) ktime_to_ns ( delta ) > > 10 ;
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Firmware loaded in %llu usecs " , duration ) ;
2015-07-01 13:20:26 +03:00
done :
release_firmware ( fw ) ;
if ( err < 0 )
return err ;
2015-08-25 18:55:44 +03:00
/* We need to restore the default speed before Intel reset */
if ( speed_change ) {
err = intel_set_baudrate ( hu , init_speed ) ;
if ( err )
return err ;
}
2015-07-01 13:20:26 +03:00
calltime = ktime_get ( ) ;
set_bit ( STATE_BOOTING , & intel - > flags ) ;
skb = __hci_cmd_sync ( hdev , 0xfc01 , sizeof ( reset_param ) , reset_param ,
HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) )
return PTR_ERR ( skb ) ;
kfree_skb ( skb ) ;
/* The bootloader will not indicate when the device is ready. This
* is done by the operational firmware sending bootup notification .
*
* Booting into operational firmware should not take longer than
* 1 second . However if that happens , then just fail the setup
* since something went wrong .
*/
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Waiting for device to boot " ) ;
2015-07-01 13:20:26 +03:00
2015-08-27 08:21:51 +03:00
err = intel_wait_booting ( hu ) ;
if ( err )
return err ;
2015-07-01 13:20:26 +03:00
2015-08-27 08:21:51 +03:00
clear_bit ( STATE_BOOTING , & intel - > flags ) ;
2015-07-01 13:20:26 +03:00
rettime = ktime_get ( ) ;
delta = ktime_sub ( rettime , calltime ) ;
duration = ( unsigned long long ) ktime_to_ns ( delta ) > > 10 ;
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Device booted in %llu usecs " , duration ) ;
2015-07-01 13:20:26 +03:00
2015-08-29 14:38:19 +03:00
/* Enable LPM if matching pdev with wakeup enabled */
2015-08-31 19:34:31 +03:00
mutex_lock ( & intel_device_list_lock ) ;
2015-08-29 14:38:19 +03:00
list_for_each ( p , & intel_device_list ) {
struct intel_device * dev = list_entry ( p , struct intel_device ,
list ) ;
if ( hu - > tty - > dev - > parent = = dev - > pdev - > dev . parent ) {
if ( device_may_wakeup ( & dev - > pdev - > dev ) )
idev = dev ;
break ;
}
}
2015-08-31 19:34:31 +03:00
mutex_unlock ( & intel_device_list_lock ) ;
2015-08-29 14:38:19 +03:00
if ( ! idev )
goto no_lpm ;
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Enabling LPM " ) ;
2015-08-29 14:38:19 +03:00
skb = __hci_cmd_sync ( hdev , 0xfc8b , sizeof ( lpm_param ) , lpm_param ,
HCI_CMD_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Failed to enable LPM " ) ;
2015-08-29 14:38:19 +03:00
goto no_lpm ;
}
kfree_skb ( skb ) ;
set_bit ( STATE_LPM_ENABLED , & intel - > flags ) ;
no_lpm :
2015-09-04 18:54:35 +03:00
/* Ignore errors, device can work without DDC parameters */
btintel_load_ddc_config ( hdev , fwname ) ;
2015-08-25 18:55:44 +03:00
skb = __hci_cmd_sync ( hdev , HCI_OP_RESET , 0 , NULL , HCI_CMD_TIMEOUT ) ;
if ( IS_ERR ( skb ) )
return PTR_ERR ( skb ) ;
kfree_skb ( skb ) ;
if ( speed_change ) {
err = intel_set_baudrate ( hu , oper_speed ) ;
if ( err )
return err ;
}
2015-08-31 19:34:30 +03:00
bt_dev_info ( hdev , " Setup complete " ) ;
2015-08-25 18:55:44 +03:00
2015-07-01 13:20:26 +03:00
clear_bit ( STATE_BOOTLOADER , & intel - > flags ) ;
return 0 ;
}
static int intel_recv_event ( struct hci_dev * hdev , struct sk_buff * skb )
{
struct hci_uart * hu = hci_get_drvdata ( hdev ) ;
struct intel_data * intel = hu - > priv ;
struct hci_event_hdr * hdr ;
2015-08-27 08:21:51 +03:00
if ( ! test_bit ( STATE_BOOTLOADER , & intel - > flags ) & &
! test_bit ( STATE_BOOTING , & intel - > flags ) )
2015-07-01 13:20:26 +03:00
goto recv ;
hdr = ( void * ) skb - > data ;
/* When the firmware loading completes the device sends
* out a vendor specific event indicating the result of
* the firmware loading .
*/
if ( skb - > len = = 7 & & hdr - > evt = = 0xff & & hdr - > plen = = 0x05 & &
skb - > data [ 2 ] = = 0x06 ) {
if ( skb - > data [ 3 ] ! = 0x00 )
set_bit ( STATE_FIRMWARE_FAILED , & intel - > flags ) ;
if ( test_and_clear_bit ( STATE_DOWNLOADING , & intel - > flags ) & &
test_bit ( STATE_FIRMWARE_LOADED , & intel - > flags ) ) {
smp_mb__after_atomic ( ) ;
wake_up_bit ( & intel - > flags , STATE_DOWNLOADING ) ;
}
/* When switching to the operational firmware the device
* sends a vendor specific event indicating that the bootup
* completed .
*/
} else if ( skb - > len = = 9 & & hdr - > evt = = 0xff & & hdr - > plen = = 0x07 & &
skb - > data [ 2 ] = = 0x02 ) {
if ( test_and_clear_bit ( STATE_BOOTING , & intel - > flags ) ) {
smp_mb__after_atomic ( ) ;
wake_up_bit ( & intel - > flags , STATE_BOOTING ) ;
}
}
recv :
return hci_recv_frame ( hdev , skb ) ;
}
2015-08-29 14:38:19 +03:00
static void intel_recv_lpm_notify ( struct hci_dev * hdev , int value )
{
struct hci_uart * hu = hci_get_drvdata ( hdev ) ;
struct intel_data * intel = hu - > priv ;
2015-08-31 19:34:30 +03:00
bt_dev_dbg ( hdev , " TX idle notification (%d) " , value ) ;
2015-08-29 14:38:19 +03:00
2015-09-02 13:04:13 +03:00
if ( value ) {
2015-08-29 14:38:19 +03:00
set_bit ( STATE_TX_ACTIVE , & intel - > flags ) ;
2015-09-02 13:04:13 +03:00
schedule_work ( & intel - > busy_work ) ;
} else {
2015-08-29 14:38:19 +03:00
clear_bit ( STATE_TX_ACTIVE , & intel - > flags ) ;
2015-09-02 13:04:13 +03:00
}
2015-08-29 14:38:19 +03:00
}
static int intel_recv_lpm ( struct hci_dev * hdev , struct sk_buff * skb )
{
struct hci_lpm_pkt * lpm = ( void * ) skb - > data ;
2015-09-02 13:04:11 +03:00
struct hci_uart * hu = hci_get_drvdata ( hdev ) ;
struct intel_data * intel = hu - > priv ;
2015-08-29 14:38:19 +03:00
switch ( lpm - > opcode ) {
case LPM_OP_TX_NOTIFY :
2015-09-02 13:04:14 +03:00
if ( lpm - > dlen < 1 ) {
bt_dev_err ( hu - > hdev , " Invalid LPM notification packet " ) ;
break ;
}
intel_recv_lpm_notify ( hdev , lpm - > data [ 0 ] ) ;
2015-08-29 14:38:19 +03:00
break ;
2015-09-02 13:04:11 +03:00
case LPM_OP_SUSPEND_ACK :
set_bit ( STATE_SUSPENDED , & intel - > flags ) ;
if ( test_and_clear_bit ( STATE_LPM_TRANSACTION , & intel - > flags ) ) {
smp_mb__after_atomic ( ) ;
wake_up_bit ( & intel - > flags , STATE_LPM_TRANSACTION ) ;
}
break ;
case LPM_OP_RESUME_ACK :
clear_bit ( STATE_SUSPENDED , & intel - > flags ) ;
if ( test_and_clear_bit ( STATE_LPM_TRANSACTION , & intel - > flags ) ) {
smp_mb__after_atomic ( ) ;
wake_up_bit ( & intel - > flags , STATE_LPM_TRANSACTION ) ;
}
break ;
2015-08-29 14:38:19 +03:00
default :
2015-08-31 19:34:30 +03:00
bt_dev_err ( hdev , " Unknown LPM opcode (%02x) " , lpm - > opcode ) ;
2015-08-29 14:38:19 +03:00
break ;
}
kfree_skb ( skb ) ;
return 0 ;
}
# define INTEL_RECV_LPM \
. type = HCI_LPM_PKT , \
. hlen = HCI_LPM_HDR_SIZE , \
. loff = 1 , \
. lsize = 1 , \
. maxlen = HCI_LPM_MAX_SIZE
2015-07-01 13:20:26 +03:00
static const struct h4_recv_pkt intel_recv_pkts [ ] = {
2015-08-29 14:38:19 +03:00
{ H4_RECV_ACL , . recv = hci_recv_frame } ,
{ H4_RECV_SCO , . recv = hci_recv_frame } ,
{ H4_RECV_EVENT , . recv = intel_recv_event } ,
{ INTEL_RECV_LPM , . recv = intel_recv_lpm } ,
2015-07-01 13:20:26 +03:00
} ;
static int intel_recv ( struct hci_uart * hu , const void * data , int count )
{
struct intel_data * intel = hu - > priv ;
if ( ! test_bit ( HCI_UART_REGISTERED , & hu - > flags ) )
return - EUNATCH ;
intel - > rx_skb = h4_recv_buf ( hu - > hdev , intel - > rx_skb , data , count ,
intel_recv_pkts ,
ARRAY_SIZE ( intel_recv_pkts ) ) ;
if ( IS_ERR ( intel - > rx_skb ) ) {
int err = PTR_ERR ( intel - > rx_skb ) ;
2015-08-31 19:34:30 +03:00
bt_dev_err ( hu - > hdev , " Frame reassembly failed (%d) " , err ) ;
2015-07-01 13:20:26 +03:00
intel - > rx_skb = NULL ;
return err ;
}
return count ;
}
static int intel_enqueue ( struct hci_uart * hu , struct sk_buff * skb )
{
struct intel_data * intel = hu - > priv ;
2015-09-02 13:04:13 +03:00
struct list_head * p ;
2015-07-01 13:20:26 +03:00
BT_DBG ( " hu %p skb %p " , hu , skb ) ;
2015-09-02 13:04:13 +03:00
/* Be sure our controller is resumed and potential LPM transaction
* completed before enqueuing any packet .
*/
mutex_lock ( & intel_device_list_lock ) ;
list_for_each ( p , & intel_device_list ) {
struct intel_device * idev = list_entry ( p , struct intel_device ,
list ) ;
if ( hu - > tty - > dev - > parent = = idev - > pdev - > dev . parent ) {
pm_runtime_get_sync ( & idev - > pdev - > dev ) ;
pm_runtime_mark_last_busy ( & idev - > pdev - > dev ) ;
pm_runtime_put_autosuspend ( & idev - > pdev - > dev ) ;
break ;
}
}
mutex_unlock ( & intel_device_list_lock ) ;
2015-07-01 13:20:26 +03:00
skb_queue_tail ( & intel - > txq , skb ) ;
return 0 ;
}
static struct sk_buff * intel_dequeue ( struct hci_uart * hu )
{
struct intel_data * intel = hu - > priv ;
struct sk_buff * skb ;
skb = skb_dequeue ( & intel - > txq ) ;
if ( ! skb )
return skb ;
if ( test_bit ( STATE_BOOTLOADER , & intel - > flags ) & &
( bt_cb ( skb ) - > pkt_type = = HCI_COMMAND_PKT ) ) {
struct hci_command_hdr * cmd = ( void * ) skb - > data ;
__u16 opcode = le16_to_cpu ( cmd - > opcode ) ;
/* When the 0xfc01 command is issued to boot into
* the operational firmware , it will actually not
* send a command complete event . To keep the flow
* control working inject that event here .
*/
if ( opcode = = 0xfc01 )
inject_cmd_complete ( hu - > hdev , opcode ) ;
}
/* Prepend skb with frame type */
memcpy ( skb_push ( skb , 1 ) , & bt_cb ( skb ) - > pkt_type , 1 ) ;
return skb ;
}
static const struct hci_uart_proto intel_proto = {
. id = HCI_UART_INTEL ,
. name = " Intel " ,
. init_speed = 115200 ,
2015-08-25 18:55:44 +03:00
. oper_speed = 3000000 ,
2015-07-01 13:20:26 +03:00
. open = intel_open ,
. close = intel_close ,
. flush = intel_flush ,
. setup = intel_setup ,
2015-08-25 18:55:44 +03:00
. set_baudrate = intel_set_baudrate ,
2015-07-01 13:20:26 +03:00
. recv = intel_recv ,
. enqueue = intel_enqueue ,
. dequeue = intel_dequeue ,
} ;
2015-08-27 08:21:51 +03:00
# ifdef CONFIG_ACPI
static const struct acpi_device_id intel_acpi_match [ ] = {
{ " INT33E1 " , 0 } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( acpi , intel_acpi_match ) ;
static int intel_acpi_probe ( struct intel_device * idev )
{
const struct acpi_device_id * id ;
id = acpi_match_device ( intel_acpi_match , & idev - > pdev - > dev ) ;
if ( ! id )
return - ENODEV ;
return 0 ;
}
# else
static int intel_acpi_probe ( struct intel_device * idev )
{
return - ENODEV ;
}
# endif
2015-09-02 13:04:13 +03:00
# ifdef CONFIG_PM
2015-09-02 13:04:12 +03:00
static int intel_suspend ( struct device * dev )
{
struct intel_device * idev = dev_get_drvdata ( dev ) ;
dev_dbg ( dev , " intel_suspend " ) ;
mutex_lock ( & idev - > hu_lock ) ;
if ( idev - > hu )
intel_lpm_suspend ( idev - > hu ) ;
mutex_unlock ( & idev - > hu_lock ) ;
return 0 ;
}
static int intel_resume ( struct device * dev )
{
struct intel_device * idev = dev_get_drvdata ( dev ) ;
dev_dbg ( dev , " intel_resume " ) ;
mutex_lock ( & idev - > hu_lock ) ;
if ( idev - > hu )
intel_lpm_resume ( idev - > hu ) ;
mutex_unlock ( & idev - > hu_lock ) ;
return 0 ;
}
# endif
static const struct dev_pm_ops intel_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS ( intel_suspend , intel_resume )
2015-09-02 13:04:13 +03:00
SET_RUNTIME_PM_OPS ( intel_suspend , intel_resume , NULL )
2015-09-02 13:04:12 +03:00
} ;
2015-08-27 08:21:51 +03:00
static int intel_probe ( struct platform_device * pdev )
{
struct intel_device * idev ;
idev = devm_kzalloc ( & pdev - > dev , sizeof ( * idev ) , GFP_KERNEL ) ;
if ( ! idev )
return - ENOMEM ;
2015-09-02 13:04:12 +03:00
mutex_init ( & idev - > hu_lock ) ;
2015-08-27 08:21:51 +03:00
idev - > pdev = pdev ;
if ( ACPI_HANDLE ( & pdev - > dev ) ) {
int err = intel_acpi_probe ( idev ) ;
if ( err )
return err ;
} else {
return - ENODEV ;
}
idev - > reset = devm_gpiod_get_optional ( & pdev - > dev , " reset " ,
GPIOD_OUT_LOW ) ;
if ( IS_ERR ( idev - > reset ) ) {
dev_err ( & pdev - > dev , " Unable to retrieve gpio \n " ) ;
return PTR_ERR ( idev - > reset ) ;
}
2015-08-29 14:38:18 +03:00
idev - > irq = platform_get_irq ( pdev , 0 ) ;
if ( idev - > irq < 0 ) {
struct gpio_desc * host_wake ;
dev_err ( & pdev - > dev , " No IRQ, falling back to gpio-irq \n " ) ;
host_wake = devm_gpiod_get_optional ( & pdev - > dev , " host-wake " ,
GPIOD_IN ) ;
if ( IS_ERR ( host_wake ) ) {
dev_err ( & pdev - > dev , " Unable to retrieve IRQ \n " ) ;
goto no_irq ;
}
idev - > irq = gpiod_to_irq ( host_wake ) ;
if ( idev - > irq < 0 ) {
dev_err ( & pdev - > dev , " No corresponding irq for gpio \n " ) ;
goto no_irq ;
}
}
/* Only enable wake-up/irq when controller is powered */
device_set_wakeup_capable ( & pdev - > dev , true ) ;
device_wakeup_disable ( & pdev - > dev ) ;
no_irq :
2015-08-27 08:21:51 +03:00
platform_set_drvdata ( pdev , idev ) ;
/* Place this instance on the device list */
2015-08-31 19:34:31 +03:00
mutex_lock ( & intel_device_list_lock ) ;
2015-08-27 08:21:51 +03:00
list_add_tail ( & idev - > list , & intel_device_list ) ;
2015-08-31 19:34:31 +03:00
mutex_unlock ( & intel_device_list_lock ) ;
2015-08-27 08:21:51 +03:00
2015-08-29 14:38:18 +03:00
dev_info ( & pdev - > dev , " registered, gpio(%d)/irq(%d). \n " ,
desc_to_gpio ( idev - > reset ) , idev - > irq ) ;
2015-08-27 08:21:51 +03:00
return 0 ;
}
static int intel_remove ( struct platform_device * pdev )
{
struct intel_device * idev = platform_get_drvdata ( pdev ) ;
2015-08-29 14:38:18 +03:00
device_wakeup_disable ( & pdev - > dev ) ;
2015-08-31 19:34:31 +03:00
mutex_lock ( & intel_device_list_lock ) ;
2015-08-27 08:21:51 +03:00
list_del ( & idev - > list ) ;
2015-08-31 19:34:31 +03:00
mutex_unlock ( & intel_device_list_lock ) ;
2015-08-27 08:21:51 +03:00
dev_info ( & pdev - > dev , " unregistered. \n " ) ;
return 0 ;
}
static struct platform_driver intel_driver = {
. probe = intel_probe ,
. remove = intel_remove ,
. driver = {
. name = " hci_intel " ,
. acpi_match_table = ACPI_PTR ( intel_acpi_match ) ,
2015-09-02 13:04:12 +03:00
. pm = & intel_pm_ops ,
2015-08-27 08:21:51 +03:00
} ,
} ;
2015-07-01 13:20:26 +03:00
int __init intel_init ( void )
{
2015-08-27 08:21:51 +03:00
platform_driver_register ( & intel_driver ) ;
2015-07-01 13:20:26 +03:00
return hci_uart_register_proto ( & intel_proto ) ;
}
int __exit intel_deinit ( void )
{
2015-08-27 08:21:51 +03:00
platform_driver_unregister ( & intel_driver ) ;
2015-07-01 13:20:26 +03:00
return hci_uart_unregister_proto ( & intel_proto ) ;
}