Hi Dmitry, On Wed, Jul 11, 2012 at 3:15 PM, Poddar, Sourav <sourav.poddar@xxxxxx> wrote: > Hi Dmitry, > > On Tue, Jul 10, 2012 at 11:43 AM, Dmitry Torokhov > <dmitry.torokhov@xxxxxxxxx> wrote: >> Hi Sourav, >> >> On Fri, Jun 08, 2012 at 04:22:59PM +0530, Sourav Poddar wrote: >>> Update the Documentation with omap4 keypad device tree >>> binding information. >>> Add device tree support for omap4 keypad driver. >>> >>> Tested on omap4430 sdp. >>> >> >> Sorry for the delay, I have a few comments: >> >>> >>> /* platform data */ >>> pdata = pdev->dev.platform_data; >>> - if (!pdata) { >>> + if (np) { >>> + of_property_read_u32(np, "keypad,num-rows", &num_rows); >>> + of_property_read_u32(np, "keypad,num-columns", &num_cols); >>> + if (!num_rows || !num_cols) { >>> + dev_err(&pdev->dev, "number of keypad rows/columns not specified\n"); >>> + return -EINVAL; >>> + } >>> + } else if (pdata) { >>> + num_rows = pdata->rows; >>> + num_cols = pdata->cols; >>> + } else { >>> dev_err(&pdev->dev, "no platform data defined\n"); >>> return -EINVAL; >>> } >>> >> >> I believe drivers should use platform data if it is supplied and use DT >> data if platform data is omitted. This way one can override firmware >> data if needed. >> >> Does the patch below (if applied on top of your) work for you? >> > Yes, the above patch works fine for me. > Acked-by: Sourav Poddar <sourav.poddar@xxxxxx> > > Note, I did some mux setting changes in the bootloader for DT case. > To be explicit, these was done throughout for testing. Nothing specific to your incremental patch. > Thanks, > Sourav >> Thanks. >> >> -- >> Dmitry >> >> Input: omap4-keypad - misc fixes >> >> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx> >> --- >> >> drivers/input/keyboard/omap4-keypad.c | 152 ++++++++++++++++----------------- >> 1 file changed, 74 insertions(+), 78 deletions(-) >> >> >> diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c >> index d5a2d1a..033168e 100644 >> --- a/drivers/input/keyboard/omap4-keypad.c >> +++ b/drivers/input/keyboard/omap4-keypad.c >> @@ -76,7 +76,6 @@ enum { >> >> struct omap4_keypad { >> struct input_dev *input; >> - struct matrix_keymap_data *keymap_data; >> >> void __iomem *base; >> unsigned int irq; >> @@ -88,7 +87,7 @@ struct omap4_keypad { >> unsigned int row_shift; >> bool no_autorepeat; >> unsigned char key_state[8]; >> - unsigned short keymap[]; >> + unsigned short *keymap; >> }; >> >> static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset) >> @@ -211,74 +210,52 @@ static void omap4_keypad_close(struct input_dev *input) >> pm_runtime_put_sync(input->dev.parent); >> } >> >> -static struct omap4_keypad *omap_keypad_parse_dt(struct device *dev, >> - uint32_t rows, uint32_t cols, >> - struct input_dev *input_dev) >> +#ifdef CONFIG_OF >> +static int __devinit omap4_keypad_parse_dt(struct device *dev, >> + struct omap4_keypad *keypad_data) >> { >> struct device_node *np = dev->of_node; >> - struct platform_device *pdev = to_platform_device(dev); >> - struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); >> int error; >> >> - error = matrix_keypad_build_keymap(NULL, "linux,keymap", >> - rows, cols, keypad_data->keymap, input_dev); >> - if (error) { >> - dev_err(&pdev->dev, "failed to build keymap\n"); >> - input_free_device(input_dev); >> + if (!np) { >> + dev_err(dev, "missing DT data"); >> + return -EINVAL; >> + } >> + >> + of_property_read_u32(np, "keypad,num-rows", &keypad_data->rows); >> + of_property_read_u32(np, "keypad,num-columns", &keypad_data->cols); >> + if (!keypad_data->rows || !keypad_data->cols) { >> + dev_err(dev, "number of keypad rows/columns not specified\n"); >> + return -EINVAL; >> } >> >> if (of_get_property(np, "linux,input-no-autorepeat", NULL)) >> keypad_data->no_autorepeat = true; >> >> - return keypad_data; >> + return 0; >> +} >> +#else >> +static inline int omap4_keypad_parse_dt(struct device *dev, >> + struct omap4_keypad *keypad_data) >> +{ >> + return -ENOSYS; >> } >> +#endif >> >> static int __devinit omap4_keypad_probe(struct platform_device *pdev) >> { >> - struct device *dev = &pdev->dev; >> - struct device_node *np = dev->of_node; >> - const struct omap4_keypad_platform_data *pdata; >> + const struct omap4_keypad_platform_data *pdata = >> + dev_get_platdata(&pdev->dev); >> + const struct matrix_keymap_data *keymap_data = >> + pdata ? pdata->keymap_data : NULL; >> struct omap4_keypad *keypad_data; >> struct input_dev *input_dev; >> struct resource *res; >> - resource_size_t size; >> - unsigned int row_shift = 0, max_keys = 0; >> - uint32_t num_rows = 0, num_cols = 0; >> + unsigned int max_keys; >> int rev; >> int irq; >> int error; >> >> - /* platform data */ >> - pdata = pdev->dev.platform_data; >> - if (np) { >> - of_property_read_u32(np, "keypad,num-rows", &num_rows); >> - of_property_read_u32(np, "keypad,num-columns", &num_cols); >> - if (!num_rows || !num_cols) { >> - dev_err(&pdev->dev, "number of keypad rows/columns not specified\n"); >> - return -EINVAL; >> - } >> - } else if (pdata) { >> - num_rows = pdata->rows; >> - num_cols = pdata->cols; >> - } else { >> - dev_err(&pdev->dev, "no platform data defined\n"); >> - return -EINVAL; >> - } >> - >> - row_shift = get_count_order(num_cols); >> - max_keys = num_rows << row_shift; >> - >> - keypad_data = devm_kzalloc(dev, sizeof(struct omap4_keypad) + >> - max_keys * sizeof(keypad_data->keymap[0]), >> - GFP_KERNEL); >> - >> - if (!keypad_data) { >> - dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); >> - return -ENOMEM; >> - } >> - >> - platform_set_drvdata(pdev, keypad_data); >> - >> res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> if (!res) { >> dev_err(&pdev->dev, "no base address specified\n"); >> @@ -291,9 +268,24 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) >> return -EINVAL; >> } >> >> - size = resource_size(res); >> + keypad_data = kzalloc(sizeof(struct omap4_keypad), GFP_KERNEL); >> + if (!keypad_data) { >> + dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); >> + return -ENOMEM; >> + } >> + >> + keypad_data->irq = irq; >> + >> + if (pdata) { >> + keypad_data->rows = pdata->rows; >> + keypad_data->cols = pdata->cols; >> + } else { >> + error = omap4_keypad_parse_dt(&pdev->dev, keypad_data); >> + if (error) >> + return error; >> + } >> >> - res = request_mem_region(res->start, size, pdev->name); >> + res = request_mem_region(res->start, resource_size(res), pdev->name); >> if (!res) { >> dev_err(&pdev->dev, "can't request mem region\n"); >> error = -EBUSY; >> @@ -307,15 +299,11 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) >> goto err_release_mem; >> } >> >> - keypad_data->rows = num_rows; >> - keypad_data->cols = num_cols; >> - keypad_data->irq = irq; >> - keypad_data->row_shift = row_shift; >> >> /* >> - * Enable clocks for the keypad module so that we can read >> - * revision register. >> - */ >> + * Enable clocks for the keypad module so that we can read >> + * revision register. >> + */ >> pm_runtime_enable(&pdev->dev); >> error = pm_runtime_get_sync(&pdev->dev); >> if (error) { >> @@ -358,29 +346,30 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) >> input_dev->open = omap4_keypad_open; >> input_dev->close = omap4_keypad_close; >> >> - if (np) { >> - keypad_data = omap_keypad_parse_dt(&pdev->dev, >> - keypad_data->rows, keypad_data->cols, >> - input_dev); >> - } else { >> - keypad_data->keymap_data = >> - (struct matrix_keymap_data *)pdata->keymap_data; >> - error = matrix_keypad_build_keymap(keypad_data->keymap_data, >> - NULL, keypad_data->rows, keypad_data->cols, >> - keypad_data->keymap, input_dev); >> - if (error) { >> - dev_err(&pdev->dev, "failed to build keymap\n"); >> - goto err_free_input; >> - } >> - } >> - >> + input_set_capability(input_dev, EV_MSC, MSC_SCAN); >> if (!keypad_data->no_autorepeat) >> __set_bit(EV_REP, input_dev->evbit); >> >> - input_set_capability(input_dev, EV_MSC, MSC_SCAN); >> - >> input_set_drvdata(input_dev, keypad_data); >> >> + keypad_data->row_shift = get_count_order(keypad_data->cols); >> + max_keys = keypad_data->rows << keypad_data->row_shift; >> + keypad_data->keymap = kzalloc(max_keys * sizeof(keypad_data->keymap[0]), >> + GFP_KERNEL); >> + if (!keypad_data->keymap) { >> + dev_err(&pdev->dev, "Not enough memory for keymap\n"); >> + error = -ENOMEM; >> + goto err_free_input; >> + } >> + >> + error = matrix_keypad_build_keymap(keymap_data, NULL, >> + keypad_data->rows, keypad_data->cols, >> + keypad_data->keymap, input_dev); >> + if (error) { >> + dev_err(&pdev->dev, "failed to build keymap\n"); >> + goto err_free_keymap; >> + } >> + >> error = request_irq(keypad_data->irq, omap4_keypad_interrupt, >> IRQF_TRIGGER_RISING, >> "omap4-keypad", keypad_data); >> @@ -397,11 +386,14 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) >> goto err_pm_disable; >> } >> >> + platform_set_drvdata(pdev, keypad_data); >> return 0; >> >> err_pm_disable: >> pm_runtime_disable(&pdev->dev); >> free_irq(keypad_data->irq, keypad_data); >> +err_free_keymap: >> + kfree(keypad_data->keymap); >> err_free_input: >> input_free_device(input_dev); >> err_pm_put_sync: >> @@ -409,7 +401,7 @@ err_pm_put_sync: >> err_unmap: >> iounmap(keypad_data->base); >> err_release_mem: >> - release_mem_region(res->start, size); >> + release_mem_region(res->start, resource_size(res)); >> err_free_keypad: >> kfree(keypad_data); >> return error; >> @@ -431,17 +423,21 @@ static int __devexit omap4_keypad_remove(struct platform_device *pdev) >> res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> release_mem_region(res->start, resource_size(res)); >> >> + kfree(keypad_data->keymap); >> kfree(keypad_data); >> + >> platform_set_drvdata(pdev, NULL); >> >> return 0; >> } >> >> +#ifdef CONFIG_OF >> static const struct of_device_id omap_keypad_dt_match[] = { >> { .compatible = "ti,omap4-keypad" }, >> {}, >> }; >> MODULE_DEVICE_TABLE(of, omap_keypad_dt_match); >> +#endif >> >> static struct platform_driver omap4_keypad_driver = { >> .probe = omap4_keypad_probe, -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html