title: uses of container_of and dev_set_drvdata and dev_get_drvdata
body: <p>I am new to device drivers and I was learning this container_of and dev_get_drvdata and came across this driver.I removed some partof this driver so as to make it compact.</p>
  
  <pre><code>    static void tsl4531_polling_worker(struct work_struct *work)
      {
  
          u8 buf[2];
  
          struct tsl4531_data *data   = container_of(to_delayed_work(work),
                              struct tsl4531_data, work);
  
          mutex_lock(&amp;data-&gt;update_lock);
          buf[0] = DEVICE_LIGHT;
          buf[1] = GET_REQUEST;
          sam4l_send_request(data-&gt;pdata.sam4l,2,buf);
          mutex_unlock(&amp;data-&gt;update_lock);
  
      }
  
      static ssize_t store_enable_value(struct device *dev,struct device_attribute *devattr,const char *buf,size_t count){
  
          struct tsl4531_data *data = dev_get_drvdata(dev);
  
          if((buf[0] == '1') &amp;&amp; (!tsl4531_enabled)) {
              schedule_delayed_work(&amp;data-&gt;work, msecs_to_jiffies(50));
              tsl4531_enabled = 1;
  
          } else if (buf[0] == '0'){
              tsl4531_enabled = 0;
              cancel_delayed_work_sync(&amp;data-&gt;work);
              tsl4531_lux = 0;
  
          }
  
          return count;
      }
  
      static DEVICE_ATTR(enable,S_IRUGO | S_IWUGO,
                 show_enable_value, store_enable_value );        
  
      static struct attribute *tsl4531_attributes[] = {
          &amp;dev_attr_lux_show.attr,
          &amp;dev_attr_enable.attr,
          NULL
      };
  
      static const struct attribute_group tsl4531_attr_group = {
          .attrs = tsl4531_attributes,
      };
  
      void tsl4531_callback_fun(struct work_struct *work)
      {
  
          struct tsl4531_data *chip = container_of(work,struct tsl4531_data,
                      pdata.work.work);
  
          tsl4531_lux = chip-&gt;pdata.response[2];//Need to check on which response index we get lux value
  
          input_report_abs(tsl4531_dev, ABS_X,tsl4531_lux);
          input_sync(tsl4531_dev);
          schedule_delayed_work(&amp;chip-&gt;work, msecs_to_jiffies(1500));
  
      }
  
      static int __devinit tsl4531_probe(struct platform_device *pdev){
          struct tsl4531_data *chip;  
          int err=0;
  
          chip = kzalloc(sizeof(struct tsl4531_data), GFP_KERNEL);
          if (!chip){
              dev_dbg(&amp;pdev-&gt;dev, "memory not allocated for tsl4531 light sensor module.\n");
              return -ENOMEM;
          }
  
          dev_set_drvdata(&amp;pdev-&gt;dev,chip);//here we give address in chip to struct device
  
          tsl4531_dev=input_allocate_device();
          if(!tsl4531_dev) {
              dev_dbg(&amp;pdev-&gt;dev, "memory not allocated for tsl4531_dev.\n");
              return -ENOMEM;
          }
  
          err=input_register_device(tsl4531_dev);
          if(err){
              dev_dbg(&amp;pdev-&gt;dev, "input register poll the device failed ... \n");
              goto err_reg_poll;
          }
  
          mutex_init(&amp;chip-&gt;update_lock);
  
          err = sysfs_create_group(&amp;pdev-&gt;dev.kobj,&amp;tsl4531_attr_group);
          if (err){
              dev_dbg(&amp;pdev-&gt;dev, "creating sysfs group for tsl4531 sensor module failed.\n");
              goto exit_err;
          }
  
          INIT_DELAYED_WORK(&amp;chip-&gt;work, tsl4531_polling_worker);
          INIT_DELAYED_WORK(&amp;chip-&gt;pdata.work,tsl4531_callback_fun);
  
          chip-&gt;pdata.dev_id = DEVICE_LIGHT;
  
          return 0;
  
          return err;
      }
  
      static int __devexit tsl4531_remove(struct platform_device *pdev){
  
          struct tsl4531_data *data = dev_get_drvdata(&amp;pdev-&gt;dev);
  
          cancel_delayed_work_sync(&amp;data-&gt;work);
          cancel_delayed_work(&amp;data-&gt;pdata.work);
          sysfs_remove_group(&amp;pdev-&gt;dev.kobj, &amp;tsl4531_attr_group);
          unregister_sam4l_client(&amp;data-&gt;pdata);
          kfree(data);
          return 0;
      }
  
      static const struct platform_device_id tsl4531_id[] = {
          { "tsl45317", 0 },
          { }
      };
  
      static struct platform_driver tsl4531_driver = {
          .driver = {
              .owner = THIS_MODULE,
              .name  = "tsl45317",
          },
          .probe      = tsl4531_probe,
          .remove     = tsl4531_remove,
          .suspend    = tsl4531_suspend,
          .resume     = tsl4531_resume,
          .id_table   = tsl4531_id,
      };
  
  
      static int __init tsl4531_init(void){
  
          return platform_driver_register(&amp;tsl4531_driver);
      }
  
  
      static void __exit tsl4531_exit(void){
  
          platform_driver_unregister(&amp;tsl4531_driver);
      }
  </code></pre>
  
  <p>I have few doubts regarding working of container_of and dev_get_drvdata</p>
  
  <p>1)in the polling_worker function we can see one container_of macro which fetches the address to the original structure and assigned to struct tsl4531_data *data;
  2)in the probe function we can see one call to dev_set_drvdata and in store_enable_value and tsl4531 dev_get_drvdata.</p>
  
  <p>Isn't both container_of and dev_set and dev_get doing same things here?</p>