1中讲了像内核注册了平台设备驱动,现在来查找下平台驱动中的 .probe 何时调用。
参考下大虾分析的,自己确实好是没找到哪里调用的。
do_basic_setup()->driver_init()->platform_bus_init()->...初始化platform bus(虚拟总线)
|
来看下samsung_keypad_probe到底做了些什么
static int __devinit samsung_keypad_probe(struct platform_device *pdev) { const struct samsung_keypad_platdata *pdata; const struct matrix_keymap_data *keymap_data; struct samsung_keypad *keypad; struct resource *res; struct input_dev *input_dev; unsigned int row_shift; unsigned int keymap_size; int error;
pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined/n"); return -EINVAL; }
keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data defined/n"); return -EINVAL; }
if (!pdata->rows || pdata->rows > SAMSUNG_MAX_ROWS) return -EINVAL;
if (!pdata->cols || pdata->cols > SAMSUNG_MAX_COLS) return -EINVAL;
/* initialize the gpio 调用 samsung_keypad_cfg_gpio*/ if (pdata->cfg_gpio) pdata->cfg_gpio(pdata->rows, pdata->cols);
row_shift = get_count_order(pdata->cols);//3// keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]);//8* sizeof(keypad->keycodes[0] keypad = kzalloc(sizeof(*keypad) + keymap_size, GFP_KERNEL); //分配输入设备 input_dev = input_allocate_device(); if (!keypad || !input_dev) { error = -ENOMEM; goto err_free_mem; }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { error = -ENODEV; goto err_free_mem; }
keypad->base = ioremap(res->start, resource_size(res)); if (!keypad->base) { error = -EBUSY; goto err_free_mem; }
keypad->clk = clk_get(&pdev->dev, "keypad"); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get keypad clk/n"); error = PTR_ERR(keypad->clk); goto err_unmap_base; }
keypad->input_dev = input_dev; keypad->row_shift = row_shift; keypad->rows = pdata->rows; keypad->cols = pdata->cols; init_waitqueue_head(&keypad->wait);
input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_set_drvdata(input_dev, keypad);
input_dev->open = samsung_keypad_open; input_dev->close = samsung_keypad_close;
input_dev->evbit[0] = BIT_MASK(EV_KEY); if (!pdata->no_autorepeat) input_dev->evbit[0] |= BIT_MASK(EV_REP);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
input_dev->keycode = keypad->keycodes; input_dev->keycodesize = sizeof(keypad->keycodes[0]); input_dev->keycodemax = pdata->rows << row_shift;
matrix_keypad_build_keymap(keymap_data, row_shift, input_dev->keycode, input_dev->keybit);
keypad->irq = platform_get_irq(pdev, 0); if (keypad->irq < 0) { error = keypad->irq; goto err_put_clk; } //分配中断线 error = request_threaded_irq(keypad->irq, NULL, samsung_keypad_irq, IRQF_ONESHOT, dev_name(&pdev->dev), keypad); if (error) { dev_err(&pdev->dev, "failed to register keypad interrupt/n"); goto err_put_clk; }
error = input_register_device(keypad->input_dev); if (error) goto err_free_irq;
device_init_wakeup(&pdev->dev, pdata->wakeup); platform_set_drvdata(pdev, keypad); return 0;
err_free_irq: free_irq(keypad->irq, keypad); err_put_clk: clk_put(keypad->clk); err_unmap_base: iounmap(keypad->base); err_free_mem: input_free_device(input_dev); kfree(keypad);
return error; }
2011-05-13 23:16:23
|