}
 EXPORT_SYMBOL_GPL(rc_free_device);
 
+static void devm_rc_alloc_release(struct device *dev, void *res)
+{
+       rc_free_device(*(struct rc_dev **)res);
+}
+
+struct rc_dev *devm_rc_allocate_device(struct device *dev)
+{
+       struct rc_dev **dr, *rc;
+
+       dr = devres_alloc(devm_rc_alloc_release, sizeof(*dr), GFP_KERNEL);
+       if (!dr)
+               return NULL;
+
+       rc = rc_allocate_device();
+       if (!rc) {
+               devres_free(dr);
+               return NULL;
+       }
+
+       rc->dev.parent = dev;
+       rc->managed_alloc = true;
+       *dr = rc;
+       devres_add(dev, dr);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(devm_rc_allocate_device);
+
 int rc_register_device(struct rc_dev *dev)
 {
        static bool raw_init = false; /* raw decoders loaded? */
 }
 EXPORT_SYMBOL_GPL(rc_register_device);
 
+static void devm_rc_release(struct device *dev, void *res)
+{
+       rc_unregister_device(*(struct rc_dev **)res);
+}
+
+int devm_rc_register_device(struct device *parent, struct rc_dev *dev)
+{
+       struct rc_dev **dr;
+       int ret;
+
+       dr = devres_alloc(devm_rc_release, sizeof(*dr), GFP_KERNEL);
+       if (!dr)
+               return -ENOMEM;
+
+       ret = rc_register_device(dev);
+       if (ret) {
+               devres_free(dr);
+               return ret;
+       }
+
+       *dr = dev;
+       devres_add(parent, dr);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(devm_rc_register_device);
+
 void rc_unregister_device(struct rc_dev *dev)
 {
        if (!dev)
 
        ida_simple_remove(&rc_ida, dev->minor);
 
-       rc_free_device(dev);
+       if (!dev->managed_alloc)
+               rc_free_device(dev);
 }
 
 EXPORT_SYMBOL_GPL(rc_unregister_device);
 
  * struct rc_dev - represents a remote control device
  * @dev: driver model's view of this device
  * @initialized: 1 if the device init has completed, 0 otherwise
+ * @managed_alloc: devm_rc_allocate_device was used to create rc_dev
  * @sysfs_groups: sysfs attribute groups
  * @input_name: name of the input child device
  * @input_phys: physical path to the input child device
 struct rc_dev {
        struct device                   dev;
        atomic_t                        initialized;
+       bool                            managed_alloc;
        const struct attribute_group    *sysfs_groups[5];
        const char                      *input_name;
        const char                      *input_phys;
  */
 struct rc_dev *rc_allocate_device(void);
 
+/**
+ * devm_rc_allocate_device - Managed RC device allocation
+ *
+ * @dev: pointer to struct device
+ * returns a pointer to struct rc_dev.
+ */
+struct rc_dev *devm_rc_allocate_device(struct device *dev);
+
 /**
  * rc_free_device - Frees a RC device
  *
  */
 int rc_register_device(struct rc_dev *dev);
 
+/**
+ * devm_rc_register_device - Manageded registering of a RC device
+ *
+ * @parent: pointer to struct device.
+ * @dev: pointer to struct rc_dev.
+ */
+int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
+
 /**
  * rc_unregister_device - Unregisters a RC device
  *