aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2009-10-13 18:12:33 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2009-12-13 13:21:17 -0500
commit68d641efd86d901d000b888eeab5481257d49f12 (patch)
treea916769e71d50c0d20725cad60fb0402da198692
parentb18fdc4b3e5e418e5582f5403c8a05b2c67eea16 (diff)
mfd: Fix memleak in pcf50633_client_dev_register
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>
-rw-r--r--drivers/input/misc/pcf50633-input.c7
-rw-r--r--drivers/mfd/pcf50633-adc.c5
-rw-r--r--drivers/mfd/pcf50633-core.c10
-rw-r--r--drivers/power/pcf50633-charger.c3
-rw-r--r--drivers/rtc/rtc-pcf50633.c5
-rw-r--r--include/linux/mfd/pcf50633/core.h10
6 files changed, 12 insertions, 28 deletions
diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c
index 039dcb00ebd9..008de0c5834b 100644
--- a/drivers/input/misc/pcf50633-input.c
+++ b/drivers/input/misc/pcf50633-input.c
@@ -55,7 +55,6 @@ pcf50633_input_irq(int irq, void *data)
55static int __devinit pcf50633_input_probe(struct platform_device *pdev) 55static int __devinit pcf50633_input_probe(struct platform_device *pdev)
56{ 56{
57 struct pcf50633_input *input; 57 struct pcf50633_input *input;
58 struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
59 struct input_dev *input_dev; 58 struct input_dev *input_dev;
60 int ret; 59 int ret;
61 60
@@ -71,7 +70,7 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev)
71 } 70 }
72 71
73 platform_set_drvdata(pdev, input); 72 platform_set_drvdata(pdev, input);
74 input->pcf = pdata->pcf; 73 input->pcf = dev_to_pcf50633(pdev->dev.parent);
75 input->input_dev = input_dev; 74 input->input_dev = input_dev;
76 75
77 input_dev->name = "PCF50633 PMU events"; 76 input_dev->name = "PCF50633 PMU events";
@@ -85,9 +84,9 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev)
85 kfree(input); 84 kfree(input);
86 return ret; 85 return ret;
87 } 86 }
88 pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR, 87 pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYR,
89 pcf50633_input_irq, input); 88 pcf50633_input_irq, input);
90 pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF, 89 pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYF,
91 pcf50633_input_irq, input); 90 pcf50633_input_irq, input);
92 91
93 return 0; 92 return 0;
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
index 3d31e97d6a45..6d2e8466df1d 100644
--- a/drivers/mfd/pcf50633-adc.c
+++ b/drivers/mfd/pcf50633-adc.c
@@ -209,17 +209,16 @@ static void pcf50633_adc_irq(int irq, void *data)
209 209
210static int __devinit pcf50633_adc_probe(struct platform_device *pdev) 210static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
211{ 211{
212 struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
213 struct pcf50633_adc *adc; 212 struct pcf50633_adc *adc;
214 213
215 adc = kzalloc(sizeof(*adc), GFP_KERNEL); 214 adc = kzalloc(sizeof(*adc), GFP_KERNEL);
216 if (!adc) 215 if (!adc)
217 return -ENOMEM; 216 return -ENOMEM;
218 217
219 adc->pcf = pdata->pcf; 218 adc->pcf = dev_to_pcf50633(pdev->dev.parent);
220 platform_set_drvdata(pdev, adc); 219 platform_set_drvdata(pdev, adc);
221 220
222 pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ADCRDY, 221 pcf50633_register_irq(adc->pcf, PCF50633_IRQ_ADCRDY,
223 pcf50633_adc_irq, adc); 222 pcf50633_adc_irq, adc);
224 223
225 mutex_init(&adc->queue_mutex); 224 mutex_init(&adc->queue_mutex);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 48776d3018ed..69cdbdcd2e82 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -456,7 +456,6 @@ static void
456pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name, 456pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
457 struct platform_device **pdev) 457 struct platform_device **pdev)
458{ 458{
459 struct pcf50633_subdev_pdata *subdev_pdata;
460 int ret; 459 int ret;
461 460
462 *pdev = platform_device_alloc(name, -1); 461 *pdev = platform_device_alloc(name, -1);
@@ -465,15 +464,6 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
465 return; 464 return;
466 } 465 }
467 466
468 subdev_pdata = kmalloc(sizeof(*subdev_pdata), GFP_KERNEL);
469 if (!subdev_pdata) {
470 dev_err(pcf->dev, "Error allocating subdev pdata\n");
471 platform_device_put(*pdev);
472 }
473
474 subdev_pdata->pcf = pcf;
475 platform_device_add_data(*pdev, subdev_pdata, sizeof(*subdev_pdata));
476
477 (*pdev)->dev.parent = pcf->dev; 467 (*pdev)->dev.parent = pcf->dev;
478 468
479 ret = platform_device_add(*pdev); 469 ret = platform_device_add(*pdev);
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index e8b278f71781..6a84a8eb8d7a 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -303,7 +303,6 @@ static const u8 mbc_irq_handlers[] = {
303static int __devinit pcf50633_mbc_probe(struct platform_device *pdev) 303static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
304{ 304{
305 struct pcf50633_mbc *mbc; 305 struct pcf50633_mbc *mbc;
306 struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
307 int ret; 306 int ret;
308 int i; 307 int i;
309 u8 mbcs1; 308 u8 mbcs1;
@@ -313,7 +312,7 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
313 return -ENOMEM; 312 return -ENOMEM;
314 313
315 platform_set_drvdata(pdev, mbc); 314 platform_set_drvdata(pdev, mbc);
316 mbc->pcf = pdata->pcf; 315 mbc->pcf = dev_to_pcf50633(pdev->dev.parent);
317 316
318 /* Set up IRQ handlers */ 317 /* Set up IRQ handlers */
319 for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++) 318 for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++)
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
index 4c5d5d0c4cfc..9b74e9c9151c 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -277,16 +277,13 @@ static void pcf50633_rtc_irq(int irq, void *data)
277 277
278static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) 278static int __devinit pcf50633_rtc_probe(struct platform_device *pdev)
279{ 279{
280 struct pcf50633_subdev_pdata *pdata;
281 struct pcf50633_rtc *rtc; 280 struct pcf50633_rtc *rtc;
282 281
283
284 rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); 282 rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
285 if (!rtc) 283 if (!rtc)
286 return -ENOMEM; 284 return -ENOMEM;
287 285
288 pdata = pdev->dev.platform_data; 286 rtc->pcf = dev_to_pcf50633(pdev->dev.parent);
289 rtc->pcf = pdata->pcf;
290 platform_set_drvdata(pdev, rtc); 287 platform_set_drvdata(pdev, rtc);
291 rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev, 288 rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev,
292 &pcf50633_rtc_ops, THIS_MODULE); 289 &pcf50633_rtc_ops, THIS_MODULE);
diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h
index 9aba7b779fbc..d9034cc87f18 100644
--- a/include/linux/mfd/pcf50633/core.h
+++ b/include/linux/mfd/pcf50633/core.h
@@ -40,10 +40,6 @@ struct pcf50633_platform_data {
40 u8 resumers[5]; 40 u8 resumers[5];
41}; 41};
42 42
43struct pcf50633_subdev_pdata {
44 struct pcf50633 *pcf;
45};
46
47struct pcf50633_irq { 43struct pcf50633_irq {
48 void (*handler) (int, void *); 44 void (*handler) (int, void *);
49 void *data; 45 void *data;
@@ -217,5 +213,9 @@ enum pcf50633_reg_int5 {
217#define PCF50633_REG_LEDCTL 0x2a 213#define PCF50633_REG_LEDCTL 0x2a
218#define PCF50633_REG_LEDDIM 0x2b 214#define PCF50633_REG_LEDDIM 0x2b
219 215
220#endif 216static inline struct pcf50633 *dev_to_pcf50633(struct device *dev)
217{
218 return dev_get_drvdata(dev);
219}
221 220
221#endif