Commit 68d641ef authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Samuel Ortiz

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: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarPaul Fertser <fercerpav@gmail.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent b18fdc4b
...@@ -55,7 +55,6 @@ pcf50633_input_irq(int irq, void *data) ...@@ -55,7 +55,6 @@ pcf50633_input_irq(int irq, void *data)
static int __devinit pcf50633_input_probe(struct platform_device *pdev) static int __devinit pcf50633_input_probe(struct platform_device *pdev)
{ {
struct pcf50633_input *input; struct pcf50633_input *input;
struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
struct input_dev *input_dev; struct input_dev *input_dev;
int ret; int ret;
...@@ -71,7 +70,7 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev) ...@@ -71,7 +70,7 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev)
} }
platform_set_drvdata(pdev, input); platform_set_drvdata(pdev, input);
input->pcf = pdata->pcf; input->pcf = dev_to_pcf50633(pdev->dev.parent);
input->input_dev = input_dev; input->input_dev = input_dev;
input_dev->name = "PCF50633 PMU events"; input_dev->name = "PCF50633 PMU events";
...@@ -85,9 +84,9 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev) ...@@ -85,9 +84,9 @@ static int __devinit pcf50633_input_probe(struct platform_device *pdev)
kfree(input); kfree(input);
return ret; return ret;
} }
pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR, pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYR,
pcf50633_input_irq, input); pcf50633_input_irq, input);
pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF, pcf50633_register_irq(input->pcf, PCF50633_IRQ_ONKEYF,
pcf50633_input_irq, input); pcf50633_input_irq, input);
return 0; return 0;
......
...@@ -209,17 +209,16 @@ static void pcf50633_adc_irq(int irq, void *data) ...@@ -209,17 +209,16 @@ static void pcf50633_adc_irq(int irq, void *data)
static int __devinit pcf50633_adc_probe(struct platform_device *pdev) static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
{ {
struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
struct pcf50633_adc *adc; struct pcf50633_adc *adc;
adc = kzalloc(sizeof(*adc), GFP_KERNEL); adc = kzalloc(sizeof(*adc), GFP_KERNEL);
if (!adc) if (!adc)
return -ENOMEM; return -ENOMEM;
adc->pcf = pdata->pcf; adc->pcf = dev_to_pcf50633(pdev->dev.parent);
platform_set_drvdata(pdev, adc); 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); pcf50633_adc_irq, adc);
mutex_init(&adc->queue_mutex); mutex_init(&adc->queue_mutex);
......
...@@ -456,7 +456,6 @@ static void ...@@ -456,7 +456,6 @@ static void
pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name, pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
struct platform_device **pdev) struct platform_device **pdev)
{ {
struct pcf50633_subdev_pdata *subdev_pdata;
int ret; int ret;
*pdev = platform_device_alloc(name, -1); *pdev = platform_device_alloc(name, -1);
...@@ -465,15 +464,6 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name, ...@@ -465,15 +464,6 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
return; 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; (*pdev)->dev.parent = pcf->dev;
ret = platform_device_add(*pdev); ret = platform_device_add(*pdev);
......
...@@ -303,7 +303,6 @@ static const u8 mbc_irq_handlers[] = { ...@@ -303,7 +303,6 @@ static const u8 mbc_irq_handlers[] = {
static int __devinit pcf50633_mbc_probe(struct platform_device *pdev) static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
{ {
struct pcf50633_mbc *mbc; struct pcf50633_mbc *mbc;
struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
int ret; int ret;
int i; int i;
u8 mbcs1; u8 mbcs1;
...@@ -313,7 +312,7 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev) ...@@ -313,7 +312,7 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, mbc); platform_set_drvdata(pdev, mbc);
mbc->pcf = pdata->pcf; mbc->pcf = dev_to_pcf50633(pdev->dev.parent);
/* Set up IRQ handlers */ /* Set up IRQ handlers */
for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++) for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++)
......
...@@ -277,16 +277,13 @@ static void pcf50633_rtc_irq(int irq, void *data) ...@@ -277,16 +277,13 @@ static void pcf50633_rtc_irq(int irq, void *data)
static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) static int __devinit pcf50633_rtc_probe(struct platform_device *pdev)
{ {
struct pcf50633_subdev_pdata *pdata;
struct pcf50633_rtc *rtc; struct pcf50633_rtc *rtc;
rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
if (!rtc) if (!rtc)
return -ENOMEM; return -ENOMEM;
pdata = pdev->dev.platform_data; rtc->pcf = dev_to_pcf50633(pdev->dev.parent);
rtc->pcf = pdata->pcf;
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev, rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev,
&pcf50633_rtc_ops, THIS_MODULE); &pcf50633_rtc_ops, THIS_MODULE);
......
...@@ -40,10 +40,6 @@ struct pcf50633_platform_data { ...@@ -40,10 +40,6 @@ struct pcf50633_platform_data {
u8 resumers[5]; u8 resumers[5];
}; };
struct pcf50633_subdev_pdata {
struct pcf50633 *pcf;
};
struct pcf50633_irq { struct pcf50633_irq {
void (*handler) (int, void *); void (*handler) (int, void *);
void *data; void *data;
...@@ -217,5 +213,9 @@ enum pcf50633_reg_int5 { ...@@ -217,5 +213,9 @@ enum pcf50633_reg_int5 {
#define PCF50633_REG_LEDCTL 0x2a #define PCF50633_REG_LEDCTL 0x2a
#define PCF50633_REG_LEDDIM 0x2b #define PCF50633_REG_LEDDIM 0x2b
#endif static inline struct pcf50633 *dev_to_pcf50633(struct device *dev)
{
return dev_get_drvdata(dev);
}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment