diff mbox series

[3/5] HID: magicmouse: Magic Trackpad 2 USB battery capacity

Message ID 20210511182023.730524-3-jose.exposito89@gmail.com
State Superseded
Headers show
Series [1/5] HID: magicmouse: register power supply | expand

Commit Message

José Expósito May 11, 2021, 6:20 p.m. UTC
Report the battery capacity percentage for the Apple Magic Trackpad 2
when it is connected over USB.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
---
 drivers/hid/hid-magicmouse.c | 136 +++++++++++++++++++++++++++++++++++
 1 file changed, 136 insertions(+)

Comments

kernel test robot May 12, 2021, 9:39 a.m. UTC | #1
Hi "José,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hid/for-next]
[also build test ERROR on v5.13-rc1 next-20210511]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jos-Exp-sito/HID-magicmouse-register-power-supply/20210512-022327
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
config: s390-randconfig-r002-20210512 (attached as .config)
compiler: s390-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/701f395a5566b6d2fd3a78389983237668902998
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jos-Exp-sito/HID-magicmouse-register-power-supply/20210512-022327
        git checkout 701f395a5566b6d2fd3a78389983237668902998
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   s390-linux-ld: drivers/pcmcia/cistpl.o: in function `set_cis_map':
   cistpl.c:(.text+0x3a2): undefined reference to `ioremap'
   s390-linux-ld: cistpl.c:(.text+0x3dc): undefined reference to `iounmap'
   s390-linux-ld: cistpl.c:(.text+0x404): undefined reference to `iounmap'
   s390-linux-ld: cistpl.c:(.text+0x416): undefined reference to `ioremap'
   s390-linux-ld: drivers/pcmcia/cistpl.o: in function `release_cis_mem':
   cistpl.c:(.text+0xe16): undefined reference to `iounmap'
   s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_remove':
   hid-magicmouse.c:(.text+0xd2c): undefined reference to `usb_kill_urb'
>> s390-linux-ld: hid-magicmouse.c:(.text+0xd48): undefined reference to `usb_free_coherent'

>> s390-linux-ld: hid-magicmouse.c:(.text+0xd54): undefined reference to `usb_free_urb'

   s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_battery_usb_urb_complete':
   hid-magicmouse.c:(.text+0xe12): undefined reference to `usb_submit_urb'
   s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_probe':
   hid-magicmouse.c:(.text+0x1194): undefined reference to `usb_alloc_urb'
>> s390-linux-ld: hid-magicmouse.c:(.text+0x121a): undefined reference to `usb_alloc_coherent'

   s390-linux-ld: hid-magicmouse.c:(.text+0x1422): undefined reference to `usb_free_coherent'
   s390-linux-ld: hid-magicmouse.c:(.text+0x142e): undefined reference to `usb_free_urb'
>> s390-linux-ld: hid-magicmouse.c:(.text+0x1462): undefined reference to `usb_submit_urb'


---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot May 12, 2021, 11:28 a.m. UTC | #2
Hi "José,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hid/for-next]
[also build test ERROR on v5.13-rc1]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jos-Exp-sito/HID-magicmouse-register-power-supply/20210512-022327
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
config: csky-randconfig-r023-20210512 (attached as .config)
compiler: csky-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/701f395a5566b6d2fd3a78389983237668902998
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jos-Exp-sito/HID-magicmouse-register-power-supply/20210512-022327
        git checkout 701f395a5566b6d2fd3a78389983237668902998
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=csky 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "usb_alloc_coherent" [drivers/hid/hid-magicmouse.ko] undefined!

>> ERROR: modpost: "usb_alloc_urb" [drivers/hid/hid-magicmouse.ko] undefined!

>> ERROR: modpost: "usb_submit_urb" [drivers/hid/hid-magicmouse.ko] undefined!

>> ERROR: modpost: "usb_free_urb" [drivers/hid/hid-magicmouse.ko] undefined!

>> ERROR: modpost: "usb_free_coherent" [drivers/hid/hid-magicmouse.ko] undefined!

>> ERROR: modpost: "usb_kill_urb" [drivers/hid/hid-magicmouse.ko] undefined!


---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
José Expósito May 15, 2021, 6:50 p.m. UTC | #3
On Wed, May 12, 2021 at 05:39:31PM +0800, kernel test robot wrote:
> Hi "José,

> 

> Thank you for the patch! Yet something to improve:

> 

> [auto build test ERROR on hid/for-next]

> [also build test ERROR on v5.13-rc1 next-20210511]

> [If your patch is applied to the wrong git tree, kindly drop us a note.

> And when submitting patch, we suggest to use '--base' as documented in

> https://git-scm.com/docs/git-format-patch]

> 

> url:    https://github.com/0day-ci/linux/commits/Jos-Exp-sito/HID-magicmouse-register-power-supply/20210512-022327

> base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next

> config: s390-randconfig-r002-20210512 (attached as .config)

> compiler: s390-linux-gcc (GCC) 9.3.0

> reproduce (this is a W=1 build):

>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross

>         chmod +x ~/bin/make.cross

>         # https://github.com/0day-ci/linux/commit/701f395a5566b6d2fd3a78389983237668902998

>         git remote add linux-review https://github.com/0day-ci/linux

>         git fetch --no-tags linux-review Jos-Exp-sito/HID-magicmouse-register-power-supply/20210512-022327

>         git checkout 701f395a5566b6d2fd3a78389983237668902998

>         # save the attached .config to linux build tree

>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=s390 

> 

> If you fix the issue, kindly add following tag as appropriate

> Reported-by: kernel test robot <lkp@intel.com>

> 

> All errors (new ones prefixed by >>):

> 

>    s390-linux-ld: drivers/pcmcia/cistpl.o: in function `set_cis_map':

>    cistpl.c:(.text+0x3a2): undefined reference to `ioremap'

>    s390-linux-ld: cistpl.c:(.text+0x3dc): undefined reference to `iounmap'

>    s390-linux-ld: cistpl.c:(.text+0x404): undefined reference to `iounmap'

>    s390-linux-ld: cistpl.c:(.text+0x416): undefined reference to `ioremap'

>    s390-linux-ld: drivers/pcmcia/cistpl.o: in function `release_cis_mem':

>    cistpl.c:(.text+0xe16): undefined reference to `iounmap'

>    s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_remove':

>    hid-magicmouse.c:(.text+0xd2c): undefined reference to `usb_kill_urb'

> >> s390-linux-ld: hid-magicmouse.c:(.text+0xd48): undefined reference to `usb_free_coherent'

> >> s390-linux-ld: hid-magicmouse.c:(.text+0xd54): undefined reference to `usb_free_urb'

>    s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_battery_usb_urb_complete':

>    hid-magicmouse.c:(.text+0xe12): undefined reference to `usb_submit_urb'

>    s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_probe':

>    hid-magicmouse.c:(.text+0x1194): undefined reference to `usb_alloc_urb'

> >> s390-linux-ld: hid-magicmouse.c:(.text+0x121a): undefined reference to `usb_alloc_coherent'

>    s390-linux-ld: hid-magicmouse.c:(.text+0x1422): undefined reference to `usb_free_coherent'

>    s390-linux-ld: hid-magicmouse.c:(.text+0x142e): undefined reference to `usb_free_urb'

> >> s390-linux-ld: hid-magicmouse.c:(.text+0x1462): undefined reference to `usb_submit_urb'

> 

> ---

> 0-DAY CI Kernel Test Service, Intel Corporation

> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org


Hi all,

I'm a little bit confused about the build errors reported by Intel's test bot and I'd really appreciate human input.
This is the first patch I submit, so apologies in advance if I missed a basic step.

I compiled and tested every patch before submission and they all compiled and worked on this tree:
git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git

After receiving this email, I followed the instructions attached to build it and indeed it failed.
However, I reverted my changes and the kernel still didn't compile.

Is this something I need to fix?

Thank you very much in advance,
José Expósito
kernel test robot May 20, 2021, 9:18 a.m. UTC | #4
On 5/16/21 2:50 AM, José Expósito wrote:
> On Wed, May 12, 2021 at 05:39:31PM +0800, kernel test robot wrote:

>> Hi "José,

>>

>> Thank you for the patch! Yet something to improve:

>>

>> [auto build test ERROR on hid/for-next]

>> [also build test ERROR on v5.13-rc1 next-20210511]

>> [If your patch is applied to the wrong git tree, kindly drop us a note.

>> And when submitting patch, we suggest to use '--base' as documented in

>> https://git-scm.com/docs/git-format-patch]

>>

>> url:    https://github.com/0day-ci/linux/commits/Jos-Exp-sito/HID-magicmouse-register-power-supply/20210512-022327

>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next

>> config: s390-randconfig-r002-20210512 (attached as .config)

>> compiler: s390-linux-gcc (GCC) 9.3.0

>> reproduce (this is a W=1 build):

>>          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross

>>          chmod +x ~/bin/make.cross

>>          # https://github.com/0day-ci/linux/commit/701f395a5566b6d2fd3a78389983237668902998

>>          git remote add linux-review https://github.com/0day-ci/linux

>>          git fetch --no-tags linux-review Jos-Exp-sito/HID-magicmouse-register-power-supply/20210512-022327

>>          git checkout 701f395a5566b6d2fd3a78389983237668902998

>>          # save the attached .config to linux build tree

>>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=s390

>>

>> If you fix the issue, kindly add following tag as appropriate

>> Reported-by: kernel test robot <lkp@intel.com>

>>

>> All errors (new ones prefixed by >>):

>>

>>     s390-linux-ld: drivers/pcmcia/cistpl.o: in function `set_cis_map':

>>     cistpl.c:(.text+0x3a2): undefined reference to `ioremap'

>>     s390-linux-ld: cistpl.c:(.text+0x3dc): undefined reference to `iounmap'

>>     s390-linux-ld: cistpl.c:(.text+0x404): undefined reference to `iounmap'

>>     s390-linux-ld: cistpl.c:(.text+0x416): undefined reference to `ioremap'

>>     s390-linux-ld: drivers/pcmcia/cistpl.o: in function `release_cis_mem':

>>     cistpl.c:(.text+0xe16): undefined reference to `iounmap'

>>     s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_remove':

>>     hid-magicmouse.c:(.text+0xd2c): undefined reference to `usb_kill_urb'

>>>> s390-linux-ld: hid-magicmouse.c:(.text+0xd48): undefined reference to `usb_free_coherent'

>>>> s390-linux-ld: hid-magicmouse.c:(.text+0xd54): undefined reference to `usb_free_urb'

>>     s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_battery_usb_urb_complete':

>>     hid-magicmouse.c:(.text+0xe12): undefined reference to `usb_submit_urb'

>>     s390-linux-ld: drivers/hid/hid-magicmouse.o: in function `magicmouse_probe':

>>     hid-magicmouse.c:(.text+0x1194): undefined reference to `usb_alloc_urb'

>>>> s390-linux-ld: hid-magicmouse.c:(.text+0x121a): undefined reference to `usb_alloc_coherent'

>>     s390-linux-ld: hid-magicmouse.c:(.text+0x1422): undefined reference to `usb_free_coherent'

>>     s390-linux-ld: hid-magicmouse.c:(.text+0x142e): undefined reference to `usb_free_urb'

>>>> s390-linux-ld: hid-magicmouse.c:(.text+0x1462): undefined reference to `usb_submit_urb'

>> ---

>> 0-DAY CI Kernel Test Service, Intel Corporation

>> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

> Hi all,

>

> I'm a little bit confused about the build errors reported by Intel's test bot and I'd really appreciate human input.

> This is the first patch I submit, so apologies in advance if I missed a basic step.

>

> I compiled and tested every patch before submission and they all compiled and worked on this tree:

> git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git

>

> After receiving this email, I followed the instructions attached to build it and indeed it failed.

> However, I reverted my changes and the kernel still didn't compile.

>

> Is this something I need to fix?


Hi José Expósito,

I think it's related to HAS_IOMEM in drivers/usb/Kconfig:

menuconfig USB_SUPPORT
         bool "USB support"
         depends on HAS_IOMEM
         default y
         help
           This option adds core support for Universal Serial Bus (USB).
           You will also need drivers from the following menu to make 
use of it.

and I found a similar issue fixed by the below commit:

commit 1f685e6adbbe3c7b1bd9053be771b898d9efa655
Author: Randy Dunlap <rdunlap@infradead.org>
Date:   Tue Jan 5 20:25:31 2021 -0800

     ptp: ptp_ines: prevent build when HAS_IOMEM is not set

     ptp_ines.c uses devm_platform_ioremap_resource(), which is only
     built/available when CONFIG_HAS_IOMEM is enabled.
     CONFIG_HAS_IOMEM is not enabled for arch/s390/, so builds on S390
     have a build error:

     s390-linux-ld: drivers/ptp/ptp_ines.o: in function 
`ines_ptp_ctrl_probe':
     ptp_ines.c:(.text+0x17e6): undefined reference to 
`devm_platform_ioremap_resource'

     Prevent builds of ptp_ines.c when HAS_IOMEM is not set.

     Fixes: bad1eaa6ac31 ("ptp: Add a driver for InES time stamping IP 
core.")
     Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
     Reported-by: kernel test robot <lkp@intel.com>
     Link: lore.kernel.org/r/202101031125.ZEFCUiKi-lkp@intel.com
     Acked-by: Richard Cochran <richardcochran@gmail.com>
     Link: 
https://lore.kernel.org/r/20210106042531.1351-1-rdunlap@infradead.org
     Signed-off-by: Jakub Kicinski <kuba@kernel.org>

diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index d2bf05ccbbe20d..f2edef0df40f5c 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -79,6 +79,7 @@ config DP83640_PHY
  config PTP_1588_CLOCK_INES
         tristate "ZHAW InES PTP time stamping IP core"
         depends on NETWORK_PHY_TIMESTAMPING
+       depends on HAS_IOMEM
         depends on PHYLIB
         depends on PTP_1588_CLOCK
         help

Best Regards,
Rong Chen

>

> Thank you very much in advance,

> José Expósito

> _______________________________________________

> kbuild-all mailing list -- kbuild-all@lists.01.org

> To unsubscribe send an email to kbuild-all-leave@lists.01.org
José Expósito May 22, 2021, 5:41 p.m. UTC | #5
On Thu, May 20, 2021 at 05:18:51PM +0800, Rong Chen wrote: 
> Hi José Expósito,

> 

> I think it's related to HAS_IOMEM in drivers/usb/Kconfig:

> 

> menuconfig USB_SUPPORT

>         bool "USB support"

>         depends on HAS_IOMEM

>         default y

>         help

> 

> 

>           This option adds core support for Universal Serial Bus (USB).

>           You will also need drivers from the following menu to make use of

> it.

> 

> and I found a similar issue fixed by the below commit:

>

> [...]

> 

> Best Regards,

> Rong Chen


Hi Rong,

Thank you very much for taking the time to help me out with this issue, I really appreciate it.

As you mentioned, the issue was related with depends on in Kconfig, I'll email a new version of the patches.

Best regards,
Jose
diff mbox series

Patch

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index d4a58dd6d2b8..ea8a85767c39 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -16,6 +16,7 @@ 
 #include <linux/input/mt.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/usb.h>
 #include <linux/workqueue.h>
 
 #include "hid-ids.h"
@@ -58,6 +59,7 @@  MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
 #define MOUSE2_REPORT_ID   0x12
 #define DOUBLE_REPORT_ID   0xf7
 #define BT_BATTERY_REPORT_ID 0x90
+#define USB_BATTERY_EP_ADDR  0x81
 
 /* These definitions are not precise, but they're close enough.  (Bits
  * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
@@ -142,6 +144,10 @@  struct magicmouse_sc {
 		struct power_supply *ps;
 		struct power_supply_desc ps_desc;
 		int capacity;
+		struct urb *urb;
+		u8 *urb_buf;
+		int urb_buf_size;
+		dma_addr_t urb_buf_dma;
 	} battery;
 };
 
@@ -231,6 +237,112 @@  static int magicmouse_battery_get_property(struct power_supply *psy,
 	return ret;
 }
 
+static void magicmouse_battery_usb_urb_complete(struct urb *urb)
+{
+	struct magicmouse_sc *msc = urb->context;
+	int ret;
+
+	switch (urb->status) {
+	case 0:
+		msc->battery.capacity = msc->battery.urb_buf[2];
+		break;
+	case -EOVERFLOW:
+		hid_err(msc->hdev, "URB overflow\n");
+		fallthrough;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+	default:
+		break;
+	}
+
+	ret = usb_submit_urb(msc->battery.urb, GFP_ATOMIC);
+	if (ret)
+		hid_err(msc->hdev, "unable to submit URB, %d\n", ret);
+}
+
+static int magicmouse_battery_usb_probe(struct magicmouse_sc *msc)
+{
+	struct usb_interface *iface = to_usb_interface(msc->hdev->dev.parent);
+	struct usb_device *usbdev = interface_to_usbdev(iface);
+	struct usb_host_endpoint *endpoint = NULL;
+	u8 ep_address;
+	unsigned int pipe = 0;
+	int i, ret;
+
+	if (!magicmouse_can_report_battery_vendor(msc, USB_VENDOR_ID_APPLE))
+		return -EINVAL;
+
+	for (i = 0; i < sizeof(usbdev->ep_in); i++) {
+		endpoint = usbdev->ep_in[i];
+		if (endpoint) {
+			ep_address = endpoint->desc.bEndpointAddress;
+			if (ep_address == USB_BATTERY_EP_ADDR)
+				break;
+		}
+	}
+
+	if (!endpoint) {
+		hid_err(msc->hdev, "endpoint with address %d not found\n",
+			USB_BATTERY_EP_ADDR);
+		ret = -EIO;
+		goto exit;
+	}
+
+	msc->battery.urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!msc->battery.urb) {
+		hid_err(msc->hdev, "unable to alloc URB, ENOMEM\n");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	pipe = usb_rcvintpipe(usbdev, endpoint->desc.bEndpointAddress);
+	if (pipe == 0) {
+		hid_err(msc->hdev, "unable to create USB rcvintpipe\n");
+		ret = -EIO;
+		goto err_free_urb;
+	}
+
+	msc->battery.urb_buf_size = endpoint->desc.wMaxPacketSize;
+	msc->battery.urb_buf_dma = msc->battery.urb->transfer_dma;
+	msc->battery.urb_buf = usb_alloc_coherent(usbdev,
+			       msc->battery.urb_buf_size, GFP_ATOMIC,
+			       &msc->battery.urb_buf_dma);
+	if (!msc->battery.urb_buf) {
+		hid_err(msc->hdev, "unable to alloc URB buffer, ENOMEM\n");
+		ret = -ENOMEM;
+		goto err_free_urb;
+	}
+
+	usb_fill_int_urb(msc->battery.urb, usbdev, pipe, msc->battery.urb_buf,
+			 msc->battery.urb_buf_size,
+			 magicmouse_battery_usb_urb_complete, msc,
+			 endpoint->desc.bInterval);
+
+	ret = usb_submit_urb(msc->battery.urb, GFP_ATOMIC);
+	if (ret) {
+		hid_err(msc->hdev, "unable to submit URB, %d\n", ret);
+		goto err_free_urb_buf;
+	}
+
+	return 0;
+
+err_free_urb_buf:
+	usb_free_coherent(usbdev, msc->battery.urb_buf_size,
+			  msc->battery.urb_buf, msc->battery.urb_buf_dma);
+
+err_free_urb:
+	usb_free_urb(msc->battery.urb);
+
+exit:
+	msc->battery.urb = NULL;
+	msc->battery.urb_buf = NULL;
+	msc->battery.urb_buf_size = 0;
+
+	return ret;
+}
+
 static int magicmouse_battery_probe(struct hid_device *hdev)
 {
 	struct magicmouse_sc *msc = hid_get_drvdata(hdev);
@@ -269,6 +381,12 @@  static int magicmouse_battery_probe(struct hid_device *hdev)
 		return ret;
 	}
 
+	if (msc->input->id.vendor == USB_VENDOR_ID_APPLE) {
+		ret = magicmouse_battery_usb_probe(msc);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -923,7 +1041,25 @@  static int magicmouse_probe(struct hid_device *hdev,
 static void magicmouse_remove(struct hid_device *hdev)
 {
 	struct magicmouse_sc *msc = hid_get_drvdata(hdev);
+	struct usb_interface *iface;
+	struct usb_device *usbdev;
 	cancel_delayed_work_sync(&msc->work);
+
+	if (msc &&
+	    magicmouse_can_report_battery_vendor(msc, USB_VENDOR_ID_APPLE) &&
+	    msc->battery.urb && msc->battery.urb_buf) {
+		iface = to_usb_interface(hdev->dev.parent);
+		usbdev = interface_to_usbdev(iface);
+
+		usb_kill_urb(msc->battery.urb);
+
+		usb_free_coherent(usbdev, msc->battery.urb_buf_size,
+				  msc->battery.urb_buf,
+				  msc->battery.urb_buf_dma);
+
+		usb_free_urb(msc->battery.urb);
+	}
+
 	hid_hw_stop(hdev);
 }