return vivaldi_function_row_physmap_show(&atkbd->vdata, buf);
 }
 
+static struct atkbd *atkbd_from_serio(struct serio *serio)
+{
+       struct ps2dev *ps2dev = serio_get_drvdata(serio);
+
+       return container_of(ps2dev, struct atkbd, ps2dev);
+}
+
 static umode_t atkbd_attr_is_visible(struct kobject *kobj,
                                struct attribute *attr, int i)
 {
        struct device *dev = kobj_to_dev(kobj);
        struct serio *serio = to_serio_port(dev);
-       struct atkbd *atkbd = serio_get_drvdata(serio);
+       struct atkbd *atkbd = atkbd_from_serio(serio);
 
        if (attr == &atkbd_attr_function_row_physmap.attr &&
            !atkbd->vdata.num_function_row_keys)
 static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                                   unsigned int flags)
 {
-       struct atkbd *atkbd = serio_get_drvdata(serio);
+       struct atkbd *atkbd = atkbd_from_serio(serio);
        struct input_dev *dev = atkbd->dev;
        unsigned int code = data;
        int scroll = 0, hscroll = 0, click = -1;
 
 static void atkbd_cleanup(struct serio *serio)
 {
-       struct atkbd *atkbd = serio_get_drvdata(serio);
+       struct atkbd *atkbd = atkbd_from_serio(serio);
 
        atkbd_disable(atkbd);
        ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF);
 
 static void atkbd_disconnect(struct serio *serio)
 {
-       struct atkbd *atkbd = serio_get_drvdata(serio);
+       struct atkbd *atkbd = atkbd_from_serio(serio);
 
        atkbd_disable(atkbd);
 
 
 static void atkbd_parse_fwnode_data(struct serio *serio)
 {
-       struct atkbd *atkbd = serio_get_drvdata(serio);
+       struct atkbd *atkbd = atkbd_from_serio(serio);
        struct device *dev = &serio->dev;
        int n;
 
 
 static int atkbd_reconnect(struct serio *serio)
 {
-       struct atkbd *atkbd = serio_get_drvdata(serio);
+       struct atkbd *atkbd = atkbd_from_serio(serio);
        struct serio_driver *drv = serio->drv;
        int retval = -1;
 
                                ssize_t (*handler)(struct atkbd *, char *))
 {
        struct serio *serio = to_serio_port(dev);
-       struct atkbd *atkbd = serio_get_drvdata(serio);
+       struct atkbd *atkbd = atkbd_from_serio(serio);
 
        return handler(atkbd, buf);
 }
                                ssize_t (*handler)(struct atkbd *, const char *, size_t))
 {
        struct serio *serio = to_serio_port(dev);
-       struct atkbd *atkbd = serio_get_drvdata(serio);
+       struct atkbd *atkbd = atkbd_from_serio(serio);
        int retval;
 
        retval = mutex_lock_interruptible(&atkbd->mutex);
 
 
 static struct workqueue_struct *kpsmoused_wq;
 
+struct psmouse *psmouse_from_serio(struct serio *serio)
+{
+       struct ps2dev *ps2dev = serio_get_drvdata(serio);
+
+       return container_of(ps2dev, struct psmouse, ps2dev);
+}
+
 void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
 {
        input_report_key(dev, BTN_LEFT,   buttons & BIT(0));
 static irqreturn_t psmouse_interrupt(struct serio *serio,
                                     u8 data, unsigned int flags)
 {
-       struct psmouse *psmouse = serio_get_drvdata(serio);
+       struct psmouse *psmouse = psmouse_from_serio(serio);
 
        if (psmouse->state == PSMOUSE_IGNORE)
                goto out;
                goto out;
 
        if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
-               parent = serio_get_drvdata(serio->parent);
+               parent = psmouse_from_serio(serio->parent);
                psmouse_deactivate(parent);
        }
 
  */
 static void psmouse_cleanup(struct serio *serio)
 {
-       struct psmouse *psmouse = serio_get_drvdata(serio);
+       struct psmouse *psmouse = psmouse_from_serio(serio);
        struct psmouse *parent = NULL;
 
        mutex_lock(&psmouse_mutex);
 
        if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
-               parent = serio_get_drvdata(serio->parent);
+               parent = psmouse_from_serio(serio->parent);
                psmouse_deactivate(parent);
        }
 
  */
 static void psmouse_disconnect(struct serio *serio)
 {
-       struct psmouse *psmouse = serio_get_drvdata(serio);
+       struct psmouse *psmouse = psmouse_from_serio(serio);
        struct psmouse *parent = NULL;
 
        mutex_lock(&psmouse_mutex);
        mutex_lock(&psmouse_mutex);
 
        if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
-               parent = serio_get_drvdata(serio->parent);
+               parent = psmouse_from_serio(serio->parent);
                psmouse_deactivate(parent);
        }
 
         * connected to this port can be successfully identified
         */
        if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
-               parent = serio_get_drvdata(serio->parent);
+               parent = psmouse_from_serio(serio->parent);
                psmouse_deactivate(parent);
        }
 
 
        psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
 
-       serio_set_drvdata(serio, psmouse);
-
        error = serio_open(serio, drv);
        if (error)
                goto err_clear_drvdata;
 
 static int __psmouse_reconnect(struct serio *serio, bool fast_reconnect)
 {
-       struct psmouse *psmouse = serio_get_drvdata(serio);
+       struct psmouse *psmouse = psmouse_from_serio(serio);
        struct psmouse *parent = NULL;
        int (*reconnect_handler)(struct psmouse *);
        enum psmouse_type type;
        }
 
        if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
-               parent = serio_get_drvdata(serio->parent);
+               parent = psmouse_from_serio(serio->parent);
                psmouse_deactivate(parent);
        }
 
 {
        struct serio *serio = to_serio_port(dev);
        struct psmouse_attribute *attr = to_psmouse_attr(devattr);
-       struct psmouse *psmouse = serio_get_drvdata(serio);
+       struct psmouse *psmouse = psmouse_from_serio(serio);
 
        if (psmouse->protocol->smbus_companion &&
                        devattr != &psmouse_attr_protocol.dattr)
        if (retval)
                goto out;
 
-       psmouse = serio_get_drvdata(serio);
+       psmouse = psmouse_from_serio(serio);
 
        if (psmouse->protocol->smbus_companion &&
                        devattr != &psmouse_attr_protocol.dattr) {
                }
 
                if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
-                       parent = serio_get_drvdata(serio->parent);
+                       parent = psmouse_from_serio(serio->parent);
                        psmouse_deactivate(parent);
                }
 
        }
 
        if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
-               parent = serio_get_drvdata(serio->parent);
+               parent = psmouse_from_serio(serio->parent);
                if (parent->pt_deactivate)
                        parent->pt_deactivate(parent);
        }
 
        void (*pt_deactivate)(struct psmouse *psmouse);
 };
 
+struct psmouse *psmouse_from_serio(struct serio *serio);
+
 void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
                unsigned long delay);
 int psmouse_reset(struct psmouse *psmouse);
 
  ****************************************************************************/
 static int synaptics_pt_write(struct serio *serio, u8 c)
 {
-       struct psmouse *parent = serio_get_drvdata(serio->parent);
+       struct psmouse *parent = psmouse_from_serio(serio->parent);
        u8 rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
        int error;
 
 
 static int synaptics_pt_start(struct serio *serio)
 {
-       struct psmouse *parent = serio_get_drvdata(serio->parent);
+       struct psmouse *parent = psmouse_from_serio(serio->parent);
        struct synaptics_data *priv = parent->private;
 
        serio_pause_rx(parent->ps2dev.serio);
 
 static void synaptics_pt_stop(struct serio *serio)
 {
-       struct psmouse *parent = serio_get_drvdata(serio->parent);
+       struct psmouse *parent = psmouse_from_serio(serio->parent);
        struct synaptics_data *priv = parent->private;
 
        serio_pause_rx(parent->ps2dev.serio);
 
 static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet)
 {
-       struct psmouse *child = serio_get_drvdata(ptport);
+       struct psmouse *child = psmouse_from_serio(ptport);
 
        if (child && child->state == PSMOUSE_ACTIVATED) {
                serio_interrupt(ptport, packet[1], 0);
 static void synaptics_pt_activate(struct psmouse *psmouse)
 {
        struct synaptics_data *priv = psmouse->private;
-       struct psmouse *child = serio_get_drvdata(priv->pt_port);
+       struct psmouse *child = psmouse_from_serio(priv->pt_port);
 
        /* adjust the touchpad to child's choice of protocol */
        if (child) {
 
 {
        struct device *dev = kobj_to_dev(kobj);
        struct serio *serio = to_serio_port(dev);
-       struct psmouse *psmouse = serio_get_drvdata(serio);
+       struct psmouse *psmouse = psmouse_from_serio(serio);
 
        return trackpoint_is_attr_available(psmouse, attr) ? attr->mode : 0;
 }
 
        lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
        init_waitqueue_head(&ps2dev->wait);
        ps2dev->serio = serio;
+       serio_set_drvdata(serio, ps2dev);
 }
 EXPORT_SYMBOL(ps2_init);