mfd: Fix memleak in pcf50633_client_dev_register
authorLars-Peter Clausen <lars@metafoo.de>
Tue, 13 Oct 2009 22:12:33 +0000 (02:12 +0400)
committerSamuel Ortiz <sameo@linux.intel.com>
Sun, 13 Dec 2009 18:21:17 +0000 (19:21 +0100)
Since platform_device_add_data copies the passed data, the allocated
subdev_pdata is never freed. A simple fix would be to either free subdev_pdata
or put it onto the stack. But since the pcf50633 child devices can rely on
beeing children of the pcf50633 core device it's much more elegant to get access
to pcf50633 core structure through that link. This allows to get completly rid
of pcf5033_subdev_pdata.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Paul Fertser <fercerpav@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/input/misc/pcf50633-input.c
drivers/mfd/pcf50633-adc.c
drivers/mfd/pcf50633-core.c
drivers/power/pcf50633-charger.c
drivers/rtc/rtc-pcf50633.c
include/linux/mfd/pcf50633/core.h

index 039dcb00ebd96250efea2a7b5903cb4521dee60f..008de0c5834b711d5efbf2de439f0104a3019916 100644 (file)
@@ -55,7 +55,6 @@ pcf50633_input_irq(int irq, void *data)
 static int __devinit pcf50633_input_probe(struct platform_device *pdev)
 {
        struct pcf50633_input *input;
-       struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
        struct input_dev *input_dev;
        int ret;
 
@@ -71,7 +70,7 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev)
        }
 
        platform_set_drvdata(pdev, input);
-       input->pcf = pdata->pcf;
+       input->pcf = dev_to_pcf50633(pdev->dev.parent);
        input->input_dev = input_dev;
 
        input_dev->name = "PCF50633 PMU events";
@@ -85,9 +84,9 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev)
                kfree(input);
                return ret;
        }
-       pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR,
+       pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYR,
                                pcf50633_input_irq, input);
-       pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF,
+       pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYF,
                                pcf50633_input_irq, input);
 
        return 0;
index 3d31e97d6a4553ab18f1752deec8ef5a76ce12de..6d2e8466df1dd804d2943144f9a8564309f76f96 100644 (file)
@@ -209,17 +209,16 @@ static void pcf50633_adc_irq(int irq, void *data)
 
 static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
 {
-       struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
        struct pcf50633_adc *adc;
 
        adc = kzalloc(sizeof(*adc), GFP_KERNEL);
        if (!adc)
                return -ENOMEM;
 
-       adc->pcf = pdata->pcf;
+       adc->pcf = dev_to_pcf50633(pdev->dev.parent);
        platform_set_drvdata(pdev, adc);
 
-       pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ADCRDY,
+       pcf50633_register_irq(adc->pcf, PCF50633_IRQ_ADCRDY,
                                        pcf50633_adc_irq, adc);
 
        mutex_init(&adc->queue_mutex);
index 48776d3018ed67e63f32fa05fc7a90df1b72332b..69cdbdcd2e823302d3036f238ca8adc69c5a4b66 100644 (file)
@@ -456,7 +456,6 @@ static void
 pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
                                                struct platform_device **pdev)
 {
-       struct pcf50633_subdev_pdata *subdev_pdata;
        int ret;
 
        *pdev = platform_device_alloc(name, -1);
@@ -465,15 +464,6 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
                return;
        }
 
-       subdev_pdata = kmalloc(sizeof(*subdev_pdata), GFP_KERNEL);
-       if (!subdev_pdata) {
-               dev_err(pcf->dev, "Error allocating subdev pdata\n");
-               platform_device_put(*pdev);
-       }
-
-       subdev_pdata->pcf = pcf;
-       platform_device_add_data(*pdev, subdev_pdata, sizeof(*subdev_pdata));
-
        (*pdev)->dev.parent = pcf->dev;
 
        ret = platform_device_add(*pdev);
index e8b278f71781a2c3590fd6029f6a1daa34ccfe0f..6a84a8eb8d7ac711ae0fa46b87ea8d63d7be80ff 100644 (file)
@@ -303,7 +303,6 @@ static const u8 mbc_irq_handlers[] = {
 static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
 {
        struct pcf50633_mbc *mbc;
-       struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
        int ret;
        int i;
        u8 mbcs1;
@@ -313,7 +312,7 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        platform_set_drvdata(pdev, mbc);
-       mbc->pcf = pdata->pcf;
+       mbc->pcf = dev_to_pcf50633(pdev->dev.parent);
 
        /* Set up IRQ handlers */
        for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++)
index 4c5d5d0c4cfcf13a4cbf462c7d03a8ad8531f99c..9b74e9c9151c6276c42256b8545508521cafcbd3 100644 (file)
@@ -277,16 +277,13 @@ static void pcf50633_rtc_irq(int irq, void *data)
 
 static int __devinit pcf50633_rtc_probe(struct platform_device *pdev)
 {
-       struct pcf50633_subdev_pdata *pdata;
        struct pcf50633_rtc *rtc;
 
-
        rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
        if (!rtc)
                return -ENOMEM;
 
-       pdata = pdev->dev.platform_data;
-       rtc->pcf = pdata->pcf;
+       rtc->pcf = dev_to_pcf50633(pdev->dev.parent);
        platform_set_drvdata(pdev, rtc);
        rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev,
                                &pcf50633_rtc_ops, THIS_MODULE);
index 9aba7b779fbc35ee13896e8643f97a976ee49758..d9034cc87f187b764979ecad8d27cd9ef77514b5 100644 (file)
@@ -40,10 +40,6 @@ struct pcf50633_platform_data {
        u8 resumers[5];
 };
 
-struct pcf50633_subdev_pdata {
-       struct pcf50633 *pcf;
-};
-
 struct pcf50633_irq {
        void (*handler) (int, void *);
        void *data;
@@ -217,5 +213,9 @@ enum pcf50633_reg_int5 {
 #define PCF50633_REG_LEDCTL 0x2a
 #define PCF50633_REG_LEDDIM 0x2b
 
-#endif
+static inline struct pcf50633 *dev_to_pcf50633(struct device *dev)
+{
+       return dev_get_drvdata(dev);
+}
 
+#endif