static struct matrix_keypad_platform_data * matrix_keypad_parse_dt(struct device *dev) { struct matrix_keypad_platform_data *pdata; struct device_node *np = dev->of_node; unsigned int *gpios; int i, nrow, ncol; if (!np) { dev_err(dev, "device lacks DT data\n"); return ERR_PTR(-ENODEV); } pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(dev, "could not allocate memory for platform data\n"); return ERR_PTR(-ENOMEM); } pdata->num_row_gpios = nrow = of_gpio_named_count(np, "row-gpios"); pdata->num_col_gpios = ncol = of_gpio_named_count(np, "col-gpios"); if (nrow <= 0 || ncol <= 0) { dev_err(dev, "number of keypad rows/columns not specified\n"); return ERR_PTR(-EINVAL); } if (of_get_property(np, "linux,no-autorepeat", NULL)) pdata->no_autorepeat = true; if (of_get_property(np, "linux,wakeup", NULL)) pdata->wakeup = true; if (of_get_property(np, "gpio-activelow", NULL)) pdata->active_low = true; of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms); of_property_read_u32(np, "col-scan-delay-us", &pdata->col_scan_delay_us); gpios = devm_kzalloc(dev, sizeof(unsigned int) * (pdata->num_row_gpios + pdata->num_col_gpios), GFP_KERNEL); if (!gpios) { dev_err(dev, "could not allocate memory for gpios\n"); return ERR_PTR(-ENOMEM); } for (i = 0; i < pdata->num_row_gpios; i++) gpios[i] = of_get_named_gpio(np, "row-gpios", i); for (i = 0; i < pdata->num_col_gpios; i++) gpios[pdata->num_row_gpios + i] = of_get_named_gpio(np, "col-gpios", i); pdata->row_gpios = gpios; pdata->col_gpios = &gpios[pdata->num_row_gpios]; return pdata; }
static int mmc_pwrseq_simple_probe(struct platform_device *pdev) { struct mmc_pwrseq_simple *spwrseq; struct device *dev = &pdev->dev; int nr_gpios; nr_gpios = of_gpio_named_count(dev->of_node, "reset-gpios"); if (nr_gpios < 0) nr_gpios = 0; spwrseq = devm_kzalloc(dev, sizeof(struct mmc_pwrseq_simple) + nr_gpios * sizeof(struct gpio_desc *), GFP_KERNEL); if (!spwrseq) return -ENOMEM; spwrseq->pwrseq.dev = dev; spwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; platform_set_drvdata(pdev, spwrseq); return mmc_pwrseq_register(&spwrseq->pwrseq); }
static int efm32_spi_probe(struct platform_device *pdev) { struct efm32_spi_ddata *ddata; struct resource *res; int ret; struct spi_master *master; struct device_node *np = pdev->dev.of_node; int num_cs, i; if (!np) return -EINVAL; num_cs = of_gpio_named_count(np, "cs-gpios"); if (num_cs < 0) return num_cs; master = spi_alloc_master(&pdev->dev, sizeof(*ddata) + num_cs * sizeof(unsigned)); if (!master) { dev_dbg(&pdev->dev, "failed to allocate spi master controller\n"); return -ENOMEM; } platform_set_drvdata(pdev, master); master->dev.of_node = pdev->dev.of_node; master->num_chipselect = num_cs; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); ddata = spi_master_get_devdata(master); ddata->bitbang.master = master; ddata->bitbang.chipselect = efm32_spi_chipselect; ddata->bitbang.setup_transfer = efm32_spi_setup_transfer; ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs; spin_lock_init(&ddata->lock); init_completion(&ddata->done); ddata->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ddata->clk)) { ret = PTR_ERR(ddata->clk); dev_err(&pdev->dev, "failed to get clock: %d\n", ret); goto err; } for (i = 0; i < num_cs; ++i) { ret = of_get_named_gpio(np, "cs-gpios", i); if (ret < 0) { dev_err(&pdev->dev, "failed to get csgpio#%u (%d)\n", i, ret); goto err; } ddata->csgpio[i] = ret; dev_dbg(&pdev->dev, "csgpio#%u = %u\n", i, ddata->csgpio[i]); ret = devm_gpio_request_one(&pdev->dev, ddata->csgpio[i], GPIOF_OUT_INIT_LOW, DRIVER_NAME); if (ret < 0) { dev_err(&pdev->dev, "failed to configure csgpio#%u (%d)\n", i, ret); goto err; } } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { ret = -ENODEV; dev_err(&pdev->dev, "failed to determine base address\n"); goto err; } if (resource_size(res) < 0x60) { ret = -EINVAL; dev_err(&pdev->dev, "memory resource too small\n"); goto err; } ddata->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(ddata->base)) { ret = PTR_ERR(ddata->base); goto err; } ret = platform_get_irq(pdev, 0); if (ret <= 0) { dev_err(&pdev->dev, "failed to get rx irq (%d)\n", ret); goto err; } ddata->rxirq = ret; ret = platform_get_irq(pdev, 1); if (ret <= 0) ret = ddata->rxirq + 1; ddata->txirq = ret; ret = clk_prepare_enable(ddata->clk); if (ret < 0) { dev_err(&pdev->dev, "failed to enable clock (%d)\n", ret); goto err; } efm32_spi_probe_dt(pdev, master, ddata); efm32_spi_write32(ddata, 0, REG_IEN); efm32_spi_write32(ddata, REG_ROUTE_TXPEN | REG_ROUTE_RXPEN | REG_ROUTE_CLKPEN | REG_ROUTE_LOCATION(ddata->pdata.location), REG_ROUTE); ret = request_irq(ddata->rxirq, efm32_spi_rxirq, 0, DRIVER_NAME " rx", ddata); if (ret) { dev_err(&pdev->dev, "failed to register rxirq (%d)\n", ret); goto err_disable_clk; } ret = request_irq(ddata->txirq, efm32_spi_txirq, 0, DRIVER_NAME " tx", ddata); if (ret) { dev_err(&pdev->dev, "failed to register txirq (%d)\n", ret); goto err_free_rx_irq; } ret = spi_bitbang_start(&ddata->bitbang); if (ret) { dev_err(&pdev->dev, "spi_bitbang_start failed (%d)\n", ret); free_irq(ddata->txirq, ddata); err_free_rx_irq: free_irq(ddata->rxirq, ddata); err_disable_clk: clk_disable_unprepare(ddata->clk); err: spi_master_put(master); } return ret; }
static int tpiu_parse_of_data(struct platform_device *pdev, struct tpiu_drvdata *drvdata) { struct device_node *node = pdev->dev.of_node; struct device_node *reg_node = NULL; struct device *dev = &pdev->dev; const __be32 *prop; int i, len, gpio, ret; uint32_t *seta_cfgs, *setb_cfgs; struct pinctrl *pctrl; reg_node = of_parse_phandle(node, "vdd-supply", 0); if (reg_node) { drvdata->reg = devm_regulator_get(dev, "vdd"); if (IS_ERR(drvdata->reg)) return PTR_ERR(drvdata->reg); prop = of_get_property(node, "qcom,vdd-voltage-level", &len); if (!prop || (len != (2 * sizeof(__be32)))) { dev_err(dev, "sdc voltage levels not specified\n"); } else { drvdata->reg_low = be32_to_cpup(&prop[0]); drvdata->reg_high = be32_to_cpup(&prop[1]); } prop = of_get_property(node, "qcom,vdd-current-level", &len); if (!prop || (len != (2 * sizeof(__be32)))) { dev_err(dev, "sdc current levels not specified\n"); } else { drvdata->reg_lpm = be32_to_cpup(&prop[0]); drvdata->reg_hpm = be32_to_cpup(&prop[1]); } of_node_put(reg_node); } else { dev_err(dev, "sdc voltage supply not specified or available\n"); } reg_node = of_parse_phandle(node, "vdd-io-supply", 0); if (reg_node) { drvdata->reg_io = devm_regulator_get(dev, "vdd-io"); if (IS_ERR(drvdata->reg_io)) return PTR_ERR(drvdata->reg_io); prop = of_get_property(node, "qcom,vdd-io-voltage-level", &len); if (!prop || (len != (2 * sizeof(__be32)))) { dev_err(dev, "sdc io voltage levels not specified\n"); } else { drvdata->reg_low_io = be32_to_cpup(&prop[0]); drvdata->reg_high_io = be32_to_cpup(&prop[1]); } prop = of_get_property(node, "qcom,vdd-io-current-level", &len); if (!prop || (len != (2 * sizeof(__be32)))) { dev_err(dev, "sdc io current levels not specified\n"); } else { drvdata->reg_lpm_io = be32_to_cpup(&prop[0]); drvdata->reg_hpm_io = be32_to_cpup(&prop[1]); } of_node_put(reg_node); } else { dev_err(dev, "sdc io voltage supply not specified or available\n"); } drvdata->out_mode = TPIU_OUT_MODE_MICTOR; drvdata->set = TPIU_SET_B; pctrl = devm_pinctrl_get(dev); if (!IS_ERR(pctrl)) { drvdata->tpiu_pctrl = devm_kzalloc(dev, sizeof(struct tpiu_pinctrl), GFP_KERNEL); if (!drvdata->tpiu_pctrl) return -ENOMEM; devm_pinctrl_put(pctrl); goto out; } dev_err(dev, "Pinctrl failed, falling back to GPIO lib\n"); drvdata->seta_gpiocnt = of_gpio_named_count(node, "qcom,seta-gpios"); if (drvdata->seta_gpiocnt > 0) { drvdata->seta_gpios = devm_kzalloc(dev, sizeof(*drvdata->seta_gpios) * drvdata->seta_gpiocnt, GFP_KERNEL); if (!drvdata->seta_gpios) return -ENOMEM; for (i = 0; i < drvdata->seta_gpiocnt; i++) { gpio = of_get_named_gpio(node, "qcom,seta-gpios", i); if (!gpio_is_valid(gpio)) return gpio; drvdata->seta_gpios[i] = gpio; } drvdata->seta_cfgs = devm_kzalloc(dev, sizeof(*drvdata->seta_cfgs) * drvdata->seta_gpiocnt, GFP_KERNEL); if (!drvdata->seta_cfgs) return -ENOMEM; seta_cfgs = devm_kzalloc(dev, sizeof(*seta_cfgs) * drvdata->seta_gpiocnt, GFP_KERNEL); if (!seta_cfgs) return -ENOMEM; ret = of_property_read_u32_array(node, "qcom,seta-gpios-func", (u32 *)seta_cfgs, drvdata->seta_gpiocnt); if (ret) return ret; for (i = 0; i < drvdata->seta_gpiocnt; i++) drvdata->seta_cfgs[i].func = seta_cfgs[i]; ret = of_property_read_u32_array(node, "qcom,seta-gpios-drv", (u32 *)seta_cfgs, drvdata->seta_gpiocnt); if (ret) return ret; for (i = 0; i < drvdata->seta_gpiocnt; i++) drvdata->seta_cfgs[i].drv = seta_cfgs[i]; ret = of_property_read_u32_array(node, "qcom,seta-gpios-pull", (u32 *)seta_cfgs, drvdata->seta_gpiocnt); if (ret) return ret; for (i = 0; i < drvdata->seta_gpiocnt; i++) drvdata->seta_cfgs[i].pull = seta_cfgs[i]; ret = of_property_read_u32_array(node, "qcom,seta-gpios-dir", (u32 *)seta_cfgs, drvdata->seta_gpiocnt); if (ret) return ret; for (i = 0; i < drvdata->seta_gpiocnt; i++) drvdata->seta_cfgs[i].dir = seta_cfgs[i]; devm_kfree(dev, seta_cfgs); } else { dev_err(dev, "seta gpios not specified\n"); } drvdata->setb_gpiocnt = of_gpio_named_count(node, "qcom,setb-gpios"); if (drvdata->setb_gpiocnt > 0) { drvdata->setb_gpios = devm_kzalloc(dev, sizeof(*drvdata->setb_gpios) * drvdata->setb_gpiocnt, GFP_KERNEL); if (!drvdata->setb_gpios) return -ENOMEM; for (i = 0; i < drvdata->setb_gpiocnt; i++) { gpio = of_get_named_gpio(node, "qcom,setb-gpios", i); if (!gpio_is_valid(gpio)) return gpio; drvdata->setb_gpios[i] = gpio; } drvdata->setb_cfgs = devm_kzalloc(dev, sizeof(*drvdata->setb_cfgs) * drvdata->setb_gpiocnt, GFP_KERNEL); if (!drvdata->setb_cfgs) return -ENOMEM; setb_cfgs = devm_kzalloc(dev, sizeof(*setb_cfgs) * drvdata->setb_gpiocnt, GFP_KERNEL); if (!setb_cfgs) return -ENOMEM; ret = of_property_read_u32_array(node, "qcom,setb-gpios-func", (u32 *)setb_cfgs, drvdata->setb_gpiocnt); if (ret) return ret; for (i = 0; i < drvdata->setb_gpiocnt; i++) drvdata->setb_cfgs[i].func = setb_cfgs[i]; ret = of_property_read_u32_array(node, "qcom,setb-gpios-drv", (u32 *)setb_cfgs, drvdata->setb_gpiocnt); if (ret) return ret; for (i = 0; i < drvdata->setb_gpiocnt; i++) drvdata->setb_cfgs[i].drv = setb_cfgs[i]; ret = of_property_read_u32_array(node, "qcom,setb-gpios-pull", (u32 *)setb_cfgs, drvdata->setb_gpiocnt); if (ret) return ret; for (i = 0; i < drvdata->setb_gpiocnt; i++) drvdata->setb_cfgs[i].pull = setb_cfgs[i]; ret = of_property_read_u32_array(node, "qcom,setb-gpios-dir", (u32 *)setb_cfgs, drvdata->setb_gpiocnt); if (ret) return ret; for (i = 0; i < drvdata->setb_gpiocnt; i++) drvdata->setb_cfgs[i].dir = setb_cfgs[i]; devm_kfree(dev, setb_cfgs); } else { dev_err(dev, "setb gpios not specified\n"); } out: drvdata->nidnt = of_property_read_bool(pdev->dev.of_node, "qcom,nidnt"); return 0; }