/* * Translate OpenFirmware node properties into platform_data */ static int gpio_keys_get_devtree_pdata(struct device *dev, struct gpio_keys_platform_data *pdata) { struct device_node *node, *pp; int i; struct gpio_keys_button *buttons; struct regulator *vddo_vreg; u32 reg; node = dev->of_node; if (node == NULL) return -ENODEV; memset(pdata, 0, sizeof *pdata); pdata->rep = !!of_get_property(node, "autorepeat", NULL); pdata->name = of_get_property(node, "input-name", NULL); vddo_vreg = devm_regulator_get(dev, "vddo"); if (IS_ERR(vddo_vreg)) dev_err(dev, "[Keys] no regulator: ignoring\n"); else{ if(!of_property_read_u32(node, "vddo-voltage", ®)) regulator_set_voltage(vddo_vreg, reg*1000, reg*1000); if(regulator_enable(vddo_vreg)) return -EINVAL; } /* First count the subnodes */ pdata->nbuttons = 0; pp = NULL; while ((pp = of_get_next_child(node, pp))) pdata->nbuttons++; if (pdata->nbuttons == 0) return -ENODEV; buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); if (!buttons) return -ENOMEM; pp = NULL; i = 0; while ((pp = of_get_next_child(node, pp))) { enum of_gpio_flags flags; if (!of_find_property(pp, "gpios", NULL)) { pdata->nbuttons--; dev_warn(dev, "Found button without gpios\n"); continue; } buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; if (of_property_read_u32(pp, "linux,code", ®)) { dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); goto out_fail; } buttons[i].code = reg; buttons[i].desc = of_get_property(pp, "label", NULL); #ifdef CONFIG_SENSORS_HALL if ((buttons[i].code == SW_FLIP) || (buttons[i].code == SW_LID)) { pdata->gpio_flip_cover = buttons[i].gpio; pdata->flip_code = buttons[i].code; pdata->nbuttons--; #ifdef CONFIG_SENSORS_HALL_IRQ_CTRL pdata->workaround_set = (of_property_read_bool(pp, "hall_wa_disable") ? false : true); #endif dev_info(dev, "[Hall_IC] device tree was founded\n"); continue; } #endif if (of_property_read_u32(pp, "linux,input-type", ®) == 0) buttons[i].type = reg; else buttons[i].type = EV_KEY; buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); if (of_property_read_u32(pp, "debounce-interval", ®) == 0) buttons[i].debounce_interval = reg; else buttons[i].debounce_interval = 5; dev_info(dev, "%s: label:%s, gpio:%d, code:%d, type:%d, debounce:%d\n", __func__, buttons[i].desc, buttons[i].gpio, buttons[i].code, buttons[i].type, buttons[i].debounce_interval); i++; } pdata->buttons = buttons; return 0; out_fail: kfree(buttons); return -ENODEV; }
/* * Translate OpenFirmware node properties into platform_data */ static int gpio_keys_get_devtree_pdata(struct device *dev, struct gpio_keys_platform_data *pdata) { struct device_node *node, *pp; int i; struct gpio_keys_button *buttons; u32 reg; node = dev->of_node; if (node == NULL) return -ENODEV; memset(pdata, 0, sizeof *pdata); pdata->rep = !!of_get_property(node, "autorepeat", NULL); pdata->name = of_get_property(node, "input-name", NULL); /* First count the subnodes */ pdata->nbuttons = 0; pp = NULL; while ((pp = of_get_next_child(node, pp))) pdata->nbuttons++; if (pdata->nbuttons == 0) return -ENODEV; buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); if (!buttons) return -ENOMEM; pp = NULL; i = 0; while ((pp = of_get_next_child(node, pp))) { enum of_gpio_flags flags; if (!of_find_property(pp, "gpios", NULL)) { pdata->nbuttons--; dev_warn(dev, "Found button without gpios\n"); continue; } buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; if (of_property_read_u32(pp, "linux,code", ®)) { dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); goto out_fail; } buttons[i].code = reg; buttons[i].desc = of_get_property(pp, "label", NULL); if (of_property_read_u32(pp, "linux,input-type", ®) == 0) buttons[i].type = reg; else buttons[i].type = EV_KEY; buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); if (of_property_read_u32(pp, "debounce-interval", ®) == 0) buttons[i].debounce_interval = reg; else buttons[i].debounce_interval = 5; i++; } pdata->buttons = buttons; return 0; out_fail: kfree(buttons); return -ENODEV; }
static int serial_omap_probe(struct platform_device *pdev) { struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev); struct uart_omap_port *up; struct resource *mem; void __iomem *base; int uartirq = 0; int wakeirq = 0; int ret; enum of_gpio_flags flags; int gpio_sel; unsigned long gpio_flags; /* The optional wakeirq may be specified in the board dts file */ if (pdev->dev.of_node) { uartirq = irq_of_parse_and_map(pdev->dev.of_node, 0); if (!uartirq) return -EPROBE_DEFER; wakeirq = irq_of_parse_and_map(pdev->dev.of_node, 1); omap_up_info = of_get_uart_port_info(&pdev->dev); pdev->dev.platform_data = omap_up_info; } else { uartirq = platform_get_irq(pdev, 0); if (uartirq < 0) return -EPROBE_DEFER; } /* Check if the UART needs to be selected */ gpio_sel = of_get_gpio_flags(pdev->dev.of_node, 0, &flags); if (gpio_is_valid(gpio_sel)) { dev_dbg(&pdev->dev, "using gpio %d for uart%d_sel\n", gpio_sel, pdev->id); gpio_flags = (flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; ret = devm_gpio_request_one(&pdev->dev, gpio_sel, gpio_flags, "uart_sel"); if (ret) { dev_err(&pdev->dev, "gpio%d request failed, ret %d\n", gpio_sel, ret); return ret; } } else if (gpio_sel == -EPROBE_DEFER) { return -EPROBE_DEFER; } up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); if (!up) return -ENOMEM; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(base)) return PTR_ERR(base); up->dev = &pdev->dev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; up->port.iotype = UPIO_MEM; up->port.irq = uartirq; up->wakeirq = wakeirq; if (!up->wakeirq) dev_info(up->port.dev, "no wakeirq for uart%d\n", up->port.line); up->port.regshift = 2; up->port.fifosize = 64; up->port.ops = &serial_omap_pops; if (pdev->dev.of_node) up->port.line = of_alias_get_id(pdev->dev.of_node, "serial"); else up->port.line = pdev->id; if (up->port.line < 0) { dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", up->port.line); ret = -ENODEV; goto err_port_line; } if (up->port.line >= OMAP_MAX_HSUART_PORTS) { dev_err(&pdev->dev, "uart ID %d > MAX %d.\n", up->port.line, OMAP_MAX_HSUART_PORTS); ret = -ENXIO; goto err_port_line; } ret = serial_omap_probe_rs485(up, pdev->dev.of_node); if (ret < 0) goto err_rs485; sprintf(up->name, "OMAP UART%d", up->port.line); up->port.mapbase = mem->start; up->port.membase = base; up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; if (!up->port.uartclk) { up->port.uartclk = DEFAULT_CLK_SPEED; dev_warn(&pdev->dev, "No clock speed specified: using default: %d\n", DEFAULT_CLK_SPEED); } up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; pm_qos_add_request(&up->pm_qos_request, PM_QOS_CPU_DMA_LATENCY, up->latency); INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); platform_set_drvdata(pdev, up); if (omap_up_info->autosuspend_timeout == 0) omap_up_info->autosuspend_timeout = -1; device_init_wakeup(up->dev, true); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, omap_up_info->autosuspend_timeout); pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); omap_serial_fill_features_erratas(up); ui[up->port.line] = up; serial_omap_add_console_port(up); ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) goto err_add_port; pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); return 0; err_add_port: pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); err_rs485: err_port_line: dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", pdev->id, __func__, ret); return ret; }
/* * Translate OpenFirmware node properties into platform_data */ static struct gpio_keys_platform_data * gpio_keys_get_devtree_pdata(struct device *dev) { struct device_node *node, *pp; struct gpio_keys_platform_data *pdata; struct gpio_keys_button *button; int error; int nbuttons; int i; node = dev->of_node; if (!node) return ERR_PTR(-ENODEV); nbuttons = of_get_child_count(node); if (nbuttons == 0) return ERR_PTR(-ENODEV); pdata = devm_kzalloc(dev, sizeof(*pdata) + nbuttons * sizeof(*button), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); pdata->buttons = (struct gpio_keys_button *)(pdata + 1); pdata->nbuttons = nbuttons; pdata->rep = !!of_get_property(node, "autorepeat", NULL); i = 0; for_each_child_of_node(node, pp) { enum of_gpio_flags flags; button = &pdata->buttons[i++]; button->gpio = of_get_gpio_flags(pp, 0, &flags); if (button->gpio < 0) { error = button->gpio; if (error != -ENOENT) { if (error != -EPROBE_DEFER) dev_err(dev, "Failed to get gpio flags, error: %d\n", error); return ERR_PTR(error); } } else { button->active_low = flags & OF_GPIO_ACTIVE_LOW; } button->irq = irq_of_parse_and_map(pp, 0); if (!gpio_is_valid(button->gpio) && !button->irq) { dev_err(dev, "Found button without gpios or irqs\n"); return ERR_PTR(-EINVAL); } if (of_property_read_u32(pp, "linux,code", &button->code)) { dev_err(dev, "Button without keycode: 0x%x\n", button->gpio); return ERR_PTR(-EINVAL); } button->desc = of_get_property(pp, "label", NULL); if (of_property_read_u32(pp, "linux,input-type", &button->type)) button->type = EV_KEY; button->wakeup = of_property_read_bool(pp, "wakeup-source") || /* legacy name */ of_property_read_bool(pp, "gpio-key,wakeup"); button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL); if (of_property_read_u32(pp, "debounce-interval", &button->debounce_interval)) button->debounce_interval = 5; } if (pdata->nbuttons == 0) return ERR_PTR(-EINVAL); return pdata; }
static int of_isp1760_probe(struct platform_device *dev) { struct isp1760 *drvdata; struct device_node *dp = dev->dev.of_node; struct resource *res; struct resource memory; struct of_irq oirq; int virq; resource_size_t res_len; int ret; unsigned int devflags = 0; enum of_gpio_flags gpio_flags; u32 bus_width = 0; drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; ret = of_address_to_resource(dp, 0, &memory); if (ret) { ret = -ENXIO; goto free_data; } res_len = resource_size(&memory); res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); if (!res) { ret = -EBUSY; goto free_data; } if (of_irq_map_one(dp, 0, &oirq)) { ret = -ENODEV; goto release_reg; } virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); if (of_device_is_compatible(dp, "nxp,usb-isp1761")) devflags |= ISP1760_FLAG_ISP1761; /* Some systems wire up only 16 of the 32 data lines */ of_property_read_u32(dp, "bus-width", &bus_width); if (bus_width == 16) devflags |= ISP1760_FLAG_BUS_WIDTH_16; if (of_get_property(dp, "port1-otg", NULL) != NULL) devflags |= ISP1760_FLAG_OTG_EN; if (of_get_property(dp, "analog-oc", NULL) != NULL) devflags |= ISP1760_FLAG_ANALOG_OC; if (of_get_property(dp, "dack-polarity", NULL) != NULL) devflags |= ISP1760_FLAG_DACK_POL_HIGH; if (of_get_property(dp, "dreq-polarity", NULL) != NULL) devflags |= ISP1760_FLAG_DREQ_POL_HIGH; drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags); if (gpio_is_valid(drvdata->rst_gpio)) { ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev)); if (!ret) { if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) { devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH; gpio_direction_output(drvdata->rst_gpio, 0); } else { gpio_direction_output(drvdata->rst_gpio, 1); } } else { drvdata->rst_gpio = ret; } } drvdata->hcd = isp1760_register(memory.start, res_len, virq, IRQF_SHARED, drvdata->rst_gpio, &dev->dev, dev_name(&dev->dev), devflags); if (IS_ERR(drvdata->hcd)) { ret = PTR_ERR(drvdata->hcd); goto free_gpio; } dev_set_drvdata(&dev->dev, drvdata); return ret; free_gpio: if (gpio_is_valid(drvdata->rst_gpio)) gpio_free(drvdata->rst_gpio); release_reg: release_mem_region(memory.start, res_len); free_data: kfree(drvdata); return ret; }
static int hi6401_irq_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct hi6401_irq *irq = NULL; enum of_gpio_flags flags; unsigned int virq; int ret = 0; int i; irq = devm_kzalloc(dev, sizeof(*irq), GFP_KERNEL); if (!irq) { dev_err(dev, "cannot allocate hi6401_irq device info\n"); return -ENOMEM; } platform_set_drvdata(pdev, irq); /* get resources */ irq->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!irq->res) { dev_err(dev, "platform_get_resource err\n"); goto err_exit; } if (!devm_request_mem_region(dev, irq->res->start, resource_size(irq->res), pdev->name)) { dev_err(dev, "cannot claim register memory\n"); goto err_exit; } irq->reg_base_addr = devm_ioremap(dev, irq->res->start, resource_size(irq->res)); if (!irq->reg_base_addr) { dev_err(dev, "cannot map register memory\n"); goto ioremap_err; } /* get pinctrl */ irq->pctrl = devm_pinctrl_get(dev); if (IS_ERR(irq->pctrl)) { dev_err(dev, "could not get pinctrl\n"); goto codec_ssi_get_err; } ret = codec_ssi_iomux_default(irq->pctrl); if (0 != ret) goto codec_ssi_iomux_err; /* get codec ssi clk */ irq->codec_ssi_clk = devm_clk_get(dev, "clk_codecssi"); if (IS_ERR(irq->codec_ssi_clk)) { pr_err("clk_get: codecssi clk not found!\n"); ret = PTR_ERR(irq->codec_ssi_clk); goto codec_ssi_clk_err; } ret = clk_prepare_enable(irq->codec_ssi_clk); if (0 != ret) { pr_err("codec_ssi_clk :clk prepare enable failed !\n"); goto codec_ssi_clk_enable_err; } /* get pmu audio clk */ irq->pmu_audio_clk = devm_clk_get(dev, "clk_pmuaudioclk"); if (IS_ERR(irq->pmu_audio_clk)) { pr_err("_clk_get: pmu_audio_clk not found!\n"); ret = PTR_ERR(irq->pmu_audio_clk); goto pmu_audio_clk_err; } ret = clk_prepare_enable(irq->pmu_audio_clk); if (0 != ret) { pr_err("pmu_audio_clk :clk prepare enable failed !\n"); goto pmu_audio_clk_enable_err; } spin_lock_init(&irq->lock); spin_lock_init(&irq->rw_lock); mutex_init(&irq->sr_mutex); mutex_init(&irq->pll_mutex); wake_lock_init(&irq->wake_lock, WAKE_LOCK_SUSPEND, "hi6401-irq"); irq->dev = dev; /* clear IRQ status */ hi6401_irq_write(irq, HI6401_REG_IRQ_0, 0xFF); hi6401_irq_write(irq, HI6401_REG_IRQ_1, 0xFF); /* mask all irqs */ hi6401_irq_write(irq, HI6401_REG_IRQM_0, 0xFF); hi6401_irq_write(irq, HI6401_REG_IRQM_1, 0xFF); irq->gpio = of_get_gpio_flags(np, 0, &flags); if (0 > irq->gpio) { dev_err(dev, "get gpio flags error\n"); ret = irq->gpio; goto get_gpio_err; } if (!gpio_is_valid(irq->gpio)) { dev_err(dev, "gpio is invalid\n"); ret = -EINVAL; goto get_gpio_err; } ret = gpio_request_one(irq->gpio, GPIOF_IN, "hi6401_irq"); if (0 > ret) { dev_err(dev, "failed to request gpio%d\n", irq->gpio); goto get_gpio_err; } irq->irq = gpio_to_irq(irq->gpio); irq->domain = irq_domain_add_simple(np, HI6401_MAX_IRQS, 0, &hi6401_domain_ops, irq); if (!irq->domain) { dev_err(dev, "irq domain error\n"); ret = -ENODEV; goto gpio_err; } for (i = 0; i < HI6401_MAX_IRQS; i++) { virq = irq_create_mapping(irq->domain, i); if (virq == NO_IRQ) { dev_err(dev, "Failed mapping hwirq\n"); ret = -ENOSPC; goto gpio_err; } irq->irqs[i] = virq; } ret = request_irq(irq->irq, hi6401_irq_handler, IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND, "hi6401_irq", irq); if (0 > ret) { dev_err(dev, "could not claim irq %d\n", ret); ret = -ENODEV; goto gpio_err; } irq->hi6401_irq_delay_wq = create_singlethread_workqueue("hi6401_irq_delay_wq"); if (!(irq->hi6401_irq_delay_wq)) { pr_err("%s(%u) : workqueue create failed", __FUNCTION__,__LINE__); ret = -ENOMEM; goto irq_delay_wq_err; } INIT_DELAYED_WORK(&irq->hi6401_irq_delay_work, hi6401_irq_work_func); irq->pll_delay_wq = create_singlethread_workqueue("pll_delay_wq"); if (!(irq->pll_delay_wq)) { pr_err("%s : pll_delay_wq create failed", __FUNCTION__); ret = -ENOMEM; goto pll_delay_wq_err; } INIT_DELAYED_WORK(&irq->pll_delay_work, hi6401_pll_work_func); g_dump_buf = (char*)kmalloc(sizeof(char)*Hi6401_SIZE_MAX, GFP_KERNEL); if (!g_dump_buf) { pr_err("%s : couldn't malloc buffer.\n",__FUNCTION__); ret = -ENOMEM; goto g_dump_buf_kmalloc_err; } memset(g_dump_buf, 0, Hi6401_SIZE_MAX); /* populate sub nodes */ of_platform_populate(np, of_hi6401_irq_child_match_tbl, NULL, dev); if (!hi6401_client) { hi6401_client = dsm_register_client(&dsm_hi6401); } return 0; g_dump_buf_kmalloc_err: if(irq->pll_delay_wq) { cancel_delayed_work(&irq->pll_delay_work); flush_workqueue(irq->pll_delay_wq); destroy_workqueue(irq->pll_delay_wq); } pll_delay_wq_err: if(irq->hi6401_irq_delay_wq) { cancel_delayed_work(&irq->hi6401_irq_delay_work); flush_workqueue(irq->hi6401_irq_delay_wq); destroy_workqueue(irq->hi6401_irq_delay_wq); } irq_delay_wq_err: free_irq(irq->irq, irq); gpio_err: gpio_free(irq->gpio); get_gpio_err: clk_disable_unprepare(irq->pmu_audio_clk); pmu_audio_clk_enable_err: devm_clk_put(dev, irq->pmu_audio_clk); pmu_audio_clk_err: clk_disable_unprepare(irq->codec_ssi_clk); codec_ssi_clk_enable_err: devm_clk_put(dev, irq->codec_ssi_clk); codec_ssi_clk_err: codec_ssi_iomux_idle(irq->pctrl); codec_ssi_iomux_err: pinctrl_put(irq->pctrl); codec_ssi_get_err: devm_iounmap(dev, irq->reg_base_addr); ioremap_err: devm_release_mem_region(dev, irq->res->start, resource_size(irq->res)); err_exit: devm_kfree(dev, irq); return ret; }