return 0;
 }
 
+/*
+ * Here we set the mouse resolution.
+ */
+
+void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
+{
+       static const unsigned char params[] = { 0, 1, 2, 2, 3 };
+       unsigned char p;
+
+       if (resolution == 0 || resolution > 200)
+               resolution = 200;
+
+       p = params[resolution / 50];
+       ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
+       psmouse->resolution = 25 << p;
+}
+
+/*
+ * Here we set the mouse report rate.
+ */
+
+static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
+{
+       static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
+       unsigned char r;
+       int i = 0;
+
+       while (rates[i] > rate) i++;
+       r = rates[i];
+       ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
+       psmouse->rate = r;
+}
+
+/*
+ * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
+ */
+
+static int psmouse_poll(struct psmouse *psmouse)
+{
+       return ps2_command(&psmouse->ps2dev, psmouse->packet,
+                          PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
+}
+
 
 /*
  * Genius NetMouse magic init.
        return 0;
 }
 
+/*
+ * Apply default settings to the psmouse structure. Most of them will
+ * be overridden by individual protocol initialization routines.
+ */
+
+static void psmouse_apply_defaults(struct psmouse *psmouse)
+{
+       struct input_dev *input_dev = psmouse->dev;
+
+       memset(input_dev->evbit, 0, sizeof(input_dev->evbit));
+       memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
+       memset(input_dev->relbit, 0, sizeof(input_dev->relbit));
+       memset(input_dev->absbit, 0, sizeof(input_dev->absbit));
+       memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit));
+
+       __set_bit(EV_KEY, input_dev->evbit);
+       __set_bit(EV_REL, input_dev->evbit);
+
+       __set_bit(BTN_LEFT, input_dev->keybit);
+       __set_bit(BTN_RIGHT, input_dev->keybit);
+
+       __set_bit(REL_X, input_dev->relbit);
+       __set_bit(REL_Y, input_dev->relbit);
+
+       psmouse->set_rate = psmouse_set_rate;
+       psmouse->set_resolution = psmouse_set_resolution;
+       psmouse->poll = psmouse_poll;
+       psmouse->protocol_handler = psmouse_process_byte;
+       psmouse->pktsize = 3;
+       psmouse->reconnect = NULL;
+       psmouse->disconnect = NULL;
+       psmouse->cleanup = NULL;
+       psmouse->pt_activate = NULL;
+       psmouse->pt_deactivate = NULL;
+}
+
+/*
+ * Apply default settings to the psmouse structure and call specified
+ * protocol detection or initialization routine.
+ */
+static int psmouse_do_detect(int (*detect)(struct psmouse *psmouse,
+                                          bool set_properties),
+                            struct psmouse *psmouse, bool set_properties)
+{
+       if (set_properties)
+               psmouse_apply_defaults(psmouse);
+
+       return detect(psmouse, set_properties);
+}
+
 /*
  * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
  * the mouse may have.
  * We always check for lifebook because it does not disturb mouse
  * (it only checks DMI information).
  */
-       if (lifebook_detect(psmouse, set_properties) == 0) {
+       if (psmouse_do_detect(lifebook_detect, psmouse, set_properties) == 0) {
                if (max_proto > PSMOUSE_IMEX) {
                        if (!set_properties || lifebook_init(psmouse) == 0)
                                return PSMOUSE_LIFEBOOK;
  * upsets the thinkingmouse).
  */
 
-       if (max_proto > PSMOUSE_IMEX && thinking_detect(psmouse, set_properties) == 0)
+       if (max_proto > PSMOUSE_IMEX &&
+           psmouse_do_detect(thinking_detect, psmouse, set_properties) == 0) {
                return PSMOUSE_THINKPS;
+       }
 
 /*
  * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol
  * support is disabled in config - we need to know if it is synaptics so we
  * can reset it properly after probing for intellimouse.
  */
-       if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) {
+       if (max_proto > PSMOUSE_PS2 &&
+           psmouse_do_detect(synaptics_detect, psmouse, set_properties) == 0) {
                synaptics_hardware = true;
 
                if (max_proto > PSMOUSE_IMEX) {
  */
        if (max_proto > PSMOUSE_IMEX) {
                ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
-               if (alps_detect(psmouse, set_properties) == 0) {
+               if (psmouse_do_detect(alps_detect,
+                                     psmouse, set_properties) == 0) {
                        if (!set_properties || alps_init(psmouse) == 0)
                                return PSMOUSE_ALPS;
 /*
  * Try OLPC HGPK touchpad.
  */
        if (max_proto > PSMOUSE_IMEX &&
-                       hgpk_detect(psmouse, set_properties) == 0) {
+           psmouse_do_detect(hgpk_detect, psmouse, set_properties) == 0) {
                if (!set_properties || hgpk_init(psmouse) == 0)
                        return PSMOUSE_HGPK;
 /*
  * Try Elantech touchpad.
  */
        if (max_proto > PSMOUSE_IMEX &&
-                       elantech_detect(psmouse, set_properties) == 0) {
+           psmouse_do_detect(elantech_detect, psmouse, set_properties) == 0) {
                if (!set_properties || elantech_init(psmouse) == 0)
                        return PSMOUSE_ELANTECH;
 /*
                max_proto = PSMOUSE_IMEX;
        }
 
-
        if (max_proto > PSMOUSE_IMEX) {
-               if (genius_detect(psmouse, set_properties) == 0)
+               if (psmouse_do_detect(genius_detect,
+                                     psmouse, set_properties) == 0)
                        return PSMOUSE_GENPS;
 
-               if (ps2pp_init(psmouse, set_properties) == 0)
+               if (psmouse_do_detect(ps2pp_init,
+                                     psmouse, set_properties) == 0)
                        return PSMOUSE_PS2PP;
 
-               if (trackpoint_detect(psmouse, set_properties) == 0)
+               if (psmouse_do_detect(trackpoint_detect,
+                                     psmouse, set_properties) == 0)
                        return PSMOUSE_TRACKPOINT;
 
-               if (touchkit_ps2_detect(psmouse, set_properties) == 0)
+               if (psmouse_do_detect(touchkit_ps2_detect,
+                                     psmouse, set_properties) == 0)
                        return PSMOUSE_TOUCHKIT_PS2;
        }
 
  * Trackpoint devices (causing TP_READ_ID command to time out).
  */
        if (max_proto > PSMOUSE_IMEX) {
-               if (fsp_detect(psmouse, set_properties) == 0) {
+               if (psmouse_do_detect(fsp_detect,
+                                     psmouse, set_properties) == 0) {
                        if (!set_properties || fsp_init(psmouse) == 0)
                                return PSMOUSE_FSP;
 /*
        ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
        psmouse_reset(psmouse);
 
-       if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0)
+       if (max_proto >= PSMOUSE_IMEX &&
+           psmouse_do_detect(im_explorer_detect,
+                             psmouse, set_properties) == 0) {
                return PSMOUSE_IMEX;
+       }
 
-       if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse, set_properties) == 0)
+       if (max_proto >= PSMOUSE_IMPS &&
+           psmouse_do_detect(intellimouse_detect,
+                             psmouse, set_properties) == 0) {
                return PSMOUSE_IMPS;
+       }
 
 /*
  * Okay, all failed, we have a standard mouse here. The number of the buttons
  * is still a question, though. We assume 3.
  */
-       ps2bare_detect(psmouse, set_properties);
+       psmouse_do_detect(ps2bare_detect, psmouse, set_properties);
 
        if (synaptics_hardware) {
 /*
        return 0;
 }
 
-/*
- * Here we set the mouse resolution.
- */
-
-void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
-{
-       static const unsigned char params[] = { 0, 1, 2, 2, 3 };
-       unsigned char p;
-
-       if (resolution == 0 || resolution > 200)
-               resolution = 200;
-
-       p = params[resolution / 50];
-       ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
-       psmouse->resolution = 25 << p;
-}
-
-/*
- * Here we set the mouse report rate.
- */
-
-static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
-{
-       static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
-       unsigned char r;
-       int i = 0;
-
-       while (rates[i] > rate) i++;
-       r = rates[i];
-       ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
-       psmouse->rate = r;
-}
-
 /*
  * psmouse_initialize() initializes the mouse to a sane state.
  */
        psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 }
 
-/*
- * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
- */
-
-static int psmouse_poll(struct psmouse *psmouse)
-{
-       return ps2_command(&psmouse->ps2dev, psmouse->packet,
-                          PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
-}
-
 
 /*
  * psmouse_resync() attempts to re-validate current protocol.
 
        input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
 
-       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
-       input_dev->keybit[BIT_WORD(BTN_MOUSE)] =
-                               BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
-       input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-
-       psmouse->set_rate = psmouse_set_rate;
-       psmouse->set_resolution = psmouse_set_resolution;
-       psmouse->poll = psmouse_poll;
-       psmouse->protocol_handler = psmouse_process_byte;
-       psmouse->pktsize = 3;
-
        if (proto && (proto->detect || proto->init)) {
+               psmouse_apply_defaults(psmouse);
+
                if (proto->detect && proto->detect(psmouse, true) < 0)
                        return -1;