/** * of_match_node - Tell if an device_node has a matching of_match structure * @matches: array of of device match structures to search in * @node: the of device structure to match against * * Low level utility function used by device matching. */ const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct device_node *node) { if (!matches) return NULL; while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; if (matches->name[0]) match &= node->name && !strcmp(matches->name, node->name); if (matches->type[0]) match &= node->type && !strcmp(matches->type, node->type); if (matches->compatible[0]) match &= of_device_is_compatible(node, matches->compatible); if (match) return matches; matches++; } return NULL; }
static int rcpm_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; if (of_device_is_compatible(np, "fsl,qoriq-rcpm-2.0")) { rcpm2_regs = of_iomap(np, 0); if (!rcpm2_regs) return -ENOMEM; rcpm_suspend_ops.enter = rcpm_v2_suspend_enter; } else { rcpm1_regs= of_iomap(np, 0); if (!rcpm1_regs) return -ENOMEM; rcpm_suspend_ops.enter = rcpm_suspend_enter; } suspend_set_ops(&rcpm_suspend_ops); dev_info(&pdev->dev, "Freescale RCPM driver\n"); return 0; }
int ufs_qcom_phy_init_clks(struct ufs_qcom_phy *phy_common) { int err; if (of_device_is_compatible(phy_common->dev->of_node, "qcom,msm8996-ufs-phy-qmp-14nm")) goto skip_txrx_clk; err = ufs_qcom_phy_clk_get(phy_common->dev, "tx_iface_clk", &phy_common->tx_iface_clk); if (err) goto out; err = ufs_qcom_phy_clk_get(phy_common->dev, "rx_iface_clk", &phy_common->rx_iface_clk); if (err) goto out; err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk_src", &phy_common->ref_clk_src); if (err) goto out; skip_txrx_clk: /* * "ref_clk_parent" is optional hence don't abort init if it's not * found. */ __ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk_parent", &phy_common->ref_clk_parent, false); err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk", &phy_common->ref_clk); out: return err; }
static int of_tl7689_int_pinmux() { struct device_node *of_pinmux = NULL; const __be32 *list; u32 size=0,pin_setting[TL7689_PINMUX_SIZE] = {0}; u32 i=0; of_pinmux = of_find_node_by_path("/pinmux"); if (!of_pinmux) { early_print("can not find pinmux in dtb\n"); while (1); } if (of_device_is_compatible(of_pinmux, pinmux_compat)) { list = of_get_property(of_pinmux,"setting_table",&size); if(size == 0 || size > TL7689_PINMUX_SIZE * sizeof(int) || list == NULL) { early_print("can not find setting_table or size err in pinmux node,size:%d,0x%x\n",size,list); while (1); } size /= sizeof(*list); early_print("find pinmux of node size is %d\n",size); if (size != TL7689_PINMUX_SIZE) size = TL7689_PINMUX_SIZE; while (i < size) { *(pin_setting+i) = be32_to_cpup(list++); early_print("pin(%d~%d) setting 0x%x\n",i*4,i*4+3,*(pin_setting+i)); i ++; } pinmux_init(pin_setting,size); return 0; } else { early_print("can not find compatible pinmux\n"); while (1); } return 0; }
static int __init intc_of_init(struct device_node *node, struct device_node *parent) { int ret; omap_nr_pending = 3; omap_nr_irqs = 96; if (WARN_ON(!node)) return -ENODEV; if (of_device_is_compatible(node, "ti,am33xx-intc")) { omap_nr_irqs = 128; omap_nr_pending = 4; } ret = omap_init_irq(-1, of_node_get(node)); if (ret < 0) return ret; set_handle_irq(omap_intc_handle_irq); return 0; }
int tilcdc_get_external_components(struct device *dev, struct component_match **match) { struct device_node *node; struct device_node *ep = NULL; int count = 0; int ret = 0; if (!tilcdc_node_has_port(dev->of_node)) return 0; while ((ep = of_graph_get_next_endpoint(dev->of_node, ep))) { node = of_graph_get_remote_port_parent(ep); if (!node || !of_device_is_available(node)) { of_node_put(node); continue; } dev_dbg(dev, "Subdevice node '%s' found\n", node->name); if (of_device_is_compatible(node, "nxp,tda998x")) { if (match) drm_of_component_match_add(dev, match, dev_match_of, node); ret = 1; } of_node_put(node); if (count++ > 1) { dev_err(dev, "Only one port is supported\n"); return -EINVAL; } } return ret; }
static int mvebu_timer_probe(struct device_d *dev) { struct clk *clk; u32 rate, div, val; timer_base = dev_request_mem_region(dev, 0); val = __raw_readl(timer_base + TIMER_CTRL_OFF); val &= ~(TIMER0_25MHZ | TIMER0_DIV_MASK); if (of_device_is_compatible(dev->device_node, "marvell,armada-370-timer")) { clk = clk_get(dev, NULL); div = TIMER_DIVIDER; val |= TIMER0_DIV(TIMER_DIVIDER_SHIFT); rate = clk_get_rate(clk) / TIMER_DIVIDER; } else { clk = clk_get(dev, "fixed"); div = 1; val |= TIMER0_25MHZ; rate = clk_get_rate(clk); } __raw_writel(val, timer_base + TIMER_CTRL_OFF); __raw_writel(0xffffffff, timer_base + TIMER0_VAL_OFF); __raw_writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); val = __raw_readl(timer_base + TIMER_CTRL_OFF); val |= TIMER0_EN | TIMER0_RELOAD_EN; __raw_writel(val, timer_base + TIMER_CTRL_OFF); cs.mult = clocksource_hz2mult(rate, cs.shift); init_clock(&cs); return 0; }
static int __devinit mxs_pinctrl_probe_dt(struct platform_device *pdev, struct mxs_pinctrl_data *d) { struct mxs_pinctrl_soc_data *soc = d->soc; struct device_node *np = pdev->dev.of_node; struct device_node *child; struct mxs_function *f; const char *gpio_compat = "fsl,mxs-gpio"; const char *fn, *fnull = ""; int i = 0, idxf = 0, idxg = 0; int ret; u32 val; child = of_get_next_child(np, NULL); if (!child) { dev_err(&pdev->dev, "no group is defined\n"); return -ENOENT; } /* Count total functions and groups */ fn = fnull; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; soc->ngroups++; /* Skip pure pinconf node */ if (of_property_read_u32(child, "reg", &val)) continue; if (strcmp(fn, child->name)) { fn = child->name; soc->nfunctions++; } } soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions * sizeof(*soc->functions), GFP_KERNEL); if (!soc->functions) return -ENOMEM; soc->groups = devm_kzalloc(&pdev->dev, soc->ngroups * sizeof(*soc->groups), GFP_KERNEL); if (!soc->groups) return -ENOMEM; /* Count groups for each function */ fn = fnull; f = &soc->functions[idxf]; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; if (of_property_read_u32(child, "reg", &val)) continue; if (strcmp(fn, child->name)) { f = &soc->functions[idxf++]; f->name = fn = child->name; } f->ngroups++; }; /* Get groups for each function */ idxf = 0; fn = fnull; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; if (of_property_read_u32(child, "reg", &val)) { ret = mxs_pinctrl_parse_group(pdev, child, idxg++, NULL); if (ret) return ret; continue; } if (strcmp(fn, child->name)) { f = &soc->functions[idxf++]; f->groups = devm_kzalloc(&pdev->dev, f->ngroups * sizeof(*f->groups), GFP_KERNEL); if (!f->groups) return -ENOMEM; fn = child->name; i = 0; } ret = mxs_pinctrl_parse_group(pdev, child, idxg++, &f->groups[i++]); if (ret) return ret; } return 0; }
static int palmas_regulators_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct palmas_pmic_platform_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *node = pdev->dev.of_node; struct palmas_pmic_driver_data *driver_data; struct regulator_config config = { }; struct palmas_pmic *pmic; const char *pdev_name; const struct of_device_id *match; int ret = 0; unsigned int reg; match = of_match_device(of_match_ptr(of_palmas_match_tbl), &pdev->dev); if (!match) return -ENODATA; driver_data = (struct palmas_pmic_driver_data *)match->data; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); if (!pmic) return -ENOMEM; if (of_device_is_compatible(node, "ti,tps659038-pmic")) { palmas_generic_regs_info[PALMAS_REG_REGEN2].ctrl_addr = TPS659038_REGEN2_CTRL; palmas_ddata.has_regen3 = false; } pmic->dev = &pdev->dev; pmic->palmas = palmas; palmas->pmic = pmic; platform_set_drvdata(pdev, pmic); pmic->palmas->pmic_ddata = driver_data; palmas_dt_to_pdata(&pdev->dev, node, pdata, driver_data); ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); if (ret) return ret; if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) pmic->smps123 = 1; if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN) pmic->smps457 = 1; config.regmap = palmas->regmap[REGULATOR_SLAVE]; config.dev = &pdev->dev; config.driver_data = pmic; pdev_name = pdev->name; ret = driver_data->smps_register(pmic, driver_data, pdata, pdev_name, config); if (ret) return ret; ret = driver_data->ldo_register(pmic, driver_data, pdata, pdev_name, config); return ret; }
static int fs_enet_probe(struct platform_device *ofdev) { const struct of_device_id *match; struct net_device *ndev; struct fs_enet_private *fep; struct fs_platform_info *fpi; const u32 *data; struct clk *clk; int err; const u8 *mac_addr; const char *phy_connection_type; int privsize, len, ret = -ENODEV; match = of_match_device(fs_enet_match, &ofdev->dev); if (!match) return -EINVAL; fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); if (!fpi) return -ENOMEM; if (!IS_FEC(match)) { data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; fpi->cp_command = *data; } fpi->rx_ring = 32; fpi->tx_ring = 32; fpi->rx_copybreak = 240; fpi->use_napi = 1; fpi->napi_weight = 17; fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link", NULL))) goto out_free_fpi; if (of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc5125-fec")) { phy_connection_type = of_get_property(ofdev->dev.of_node, "phy-connection-type", NULL); if (phy_connection_type && !strcmp("rmii", phy_connection_type)) fpi->use_rmii = 1; } /* make clock lookup non-fatal (the driver is shared among platforms), * but require enable to succeed when a clock was specified/found, * keep a reference to the clock upon successful acquisition */ clk = devm_clk_get(&ofdev->dev, "per"); if (!IS_ERR(clk)) { err = clk_prepare_enable(clk); if (err) { ret = err; goto out_free_fpi; } fpi->clk_per = clk; } privsize = sizeof(*fep) + sizeof(struct sk_buff **) * (fpi->rx_ring + fpi->tx_ring); ndev = alloc_etherdev(privsize); if (!ndev) { ret = -ENOMEM; goto out_put; } SET_NETDEV_DEV(ndev, &ofdev->dev); platform_set_drvdata(ofdev, ndev); fep = netdev_priv(ndev); fep->dev = &ofdev->dev; fep->ndev = ndev; fep->fpi = fpi; fep->ops = match->data; ret = fep->ops->setup_data(ndev); if (ret) goto out_free_dev; fep->rx_skbuff = (struct sk_buff **)&fep[1]; fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; spin_lock_init(&fep->lock); spin_lock_init(&fep->tx_lock); mac_addr = of_get_mac_address(ofdev->dev.of_node); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); ret = fep->ops->allocate_bd(ndev); if (ret) goto out_cleanup_data; fep->rx_bd_base = fep->ring_base; fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; fep->tx_ring = fpi->tx_ring; fep->rx_ring = fpi->rx_ring; ndev->netdev_ops = &fs_enet_netdev_ops; ndev->watchdog_timeo = 2 * HZ; if (fpi->use_napi) netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight); ndev->ethtool_ops = &fs_ethtool_ops; init_timer(&fep->phy_timer_list); netif_carrier_off(ndev); ret = register_netdev(ndev); if (ret) goto out_free_bd; pr_info("%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr); return 0; out_free_bd: fep->ops->free_bd(ndev); out_cleanup_data: fep->ops->cleanup_data(ndev); out_free_dev: free_netdev(ndev); out_put: of_node_put(fpi->phy_node); if (fpi->clk_per) clk_disable_unprepare(fpi->clk_per); out_free_fpi: kfree(fpi); return ret; }
static int ti_pipe3_probe(struct platform_device *pdev) { struct ti_pipe3 *phy; struct phy *generic_phy; struct phy_provider *phy_provider; struct resource *res; struct device_node *node = pdev->dev.of_node; struct device_node *control_node; struct platform_device *control_pdev; const struct of_device_id *match; struct clk *clk; phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; phy->dev = &pdev->dev; spin_lock_init(&phy->lock); if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { match = of_match_device(of_match_ptr(ti_pipe3_id_table), &pdev->dev); if (!match) return -EINVAL; phy->dpll_map = (struct pipe3_dpll_map *)match->data; if (!phy->dpll_map) { dev_err(&pdev->dev, "no DPLL data\n"); return -EINVAL; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(phy->pll_ctrl_base)) return PTR_ERR(phy->pll_ctrl_base); phy->sys_clk = devm_clk_get(phy->dev, "sysclk"); if (IS_ERR(phy->sys_clk)) { dev_err(&pdev->dev, "unable to get sysclk\n"); return -EINVAL; } } phy->refclk = devm_clk_get(phy->dev, "refclk"); if (IS_ERR(phy->refclk)) { dev_err(&pdev->dev, "unable to get refclk\n"); /* older DTBs have missing refclk in SATA PHY * so don't bail out in case of SATA PHY. */ if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) return PTR_ERR(phy->refclk); } if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); if (IS_ERR(phy->wkupclk)) { dev_err(&pdev->dev, "unable to get wkupclk\n"); return PTR_ERR(phy->wkupclk); } } else { phy->wkupclk = ERR_PTR(-ENODEV); } if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { clk = devm_clk_get(phy->dev, "dpll_ref"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "unable to get dpll ref clk\n"); return PTR_ERR(clk); } clk_set_rate(clk, 1500000000); clk = devm_clk_get(phy->dev, "dpll_ref_m2"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "unable to get dpll ref m2 clk\n"); return PTR_ERR(clk); } clk_set_rate(clk, 100000000); clk = devm_clk_get(phy->dev, "phy-div"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "unable to get phy-div clk\n"); return PTR_ERR(clk); } clk_set_rate(clk, 100000000); phy->div_clk = devm_clk_get(phy->dev, "div-clk"); if (IS_ERR(phy->div_clk)) { dev_err(&pdev->dev, "unable to get div-clk\n"); return PTR_ERR(phy->div_clk); } } else { phy->div_clk = ERR_PTR(-ENODEV); } control_node = of_parse_phandle(node, "ctrl-module", 0); if (!control_node) { dev_err(&pdev->dev, "Failed to get control device phandle\n"); return -EINVAL; } control_pdev = of_find_device_by_node(control_node); if (!control_pdev) { dev_err(&pdev->dev, "Failed to get control device\n"); return -EINVAL; } phy->control_dev = &control_pdev->dev; omap_control_phy_power(phy->control_dev, 0); platform_set_drvdata(pdev, phy); pm_runtime_enable(phy->dev); generic_phy = devm_phy_create(phy->dev, NULL, &ops); if (IS_ERR(generic_phy)) return PTR_ERR(generic_phy); phy_set_drvdata(generic_phy, phy); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); pm_runtime_get(&pdev->dev); return 0; }
static int cpm_uart_init_port(struct device_node *np, struct uart_cpm_port *pinfo) { const u32 *data; void __iomem *mem, *pram; int len; int ret; int i; data = of_get_property(np, "clock", NULL); if (data) { struct clk *clk = clk_get(NULL, (const char*)data); if (!IS_ERR(clk)) pinfo->clk = clk; } if (!pinfo->clk) { data = of_get_property(np, "fsl,cpm-brg", &len); if (!data || len != 4) { printk(KERN_ERR "CPM UART %s has no/invalid " "fsl,cpm-brg property.\n", np->name); return -EINVAL; } pinfo->brg = *data; } data = of_get_property(np, "fsl,cpm-command", &len); if (!data || len != 4) { printk(KERN_ERR "CPM UART %s has no/invalid " "fsl,cpm-command property.\n", np->name); return -EINVAL; } pinfo->command = *data; mem = of_iomap(np, 0); if (!mem) return -ENOMEM; if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") || of_device_is_compatible(np, "fsl,cpm2-scc-uart")) { pinfo->sccp = mem; pinfo->sccup = pram = cpm_uart_map_pram(pinfo, np); } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") || of_device_is_compatible(np, "fsl,cpm2-smc-uart")) { pinfo->flags |= FLAG_SMC; pinfo->smcp = mem; pinfo->smcup = pram = cpm_uart_map_pram(pinfo, np); } else { ret = -ENODEV; goto out_mem; } if (!pram) { ret = -ENOMEM; goto out_mem; } pinfo->tx_nrfifos = TX_NUM_FIFO; pinfo->tx_fifosize = TX_BUF_SIZE; pinfo->rx_nrfifos = RX_NUM_FIFO; pinfo->rx_fifosize = RX_BUF_SIZE; pinfo->port.uartclk = ppc_proc_freq; pinfo->port.mapbase = (unsigned long)mem; pinfo->port.type = PORT_CPM; pinfo->port.ops = &cpm_uart_pops, pinfo->port.iotype = UPIO_MEM; pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize; spin_lock_init(&pinfo->port.lock); pinfo->port.irq = of_irq_to_resource(np, 0, NULL); if (pinfo->port.irq == NO_IRQ) { ret = -EINVAL; goto out_pram; } for (i = 0; i < NUM_GPIOS; i++) pinfo->gpios[i] = of_get_gpio(np, i); return cpm_uart_request_port(&pinfo->port); out_pram: cpm_uart_unmap_pram(pinfo, pram); out_mem: iounmap(mem); return ret; }
static int stmmac_probe_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat, const char **mac) { struct device_node *np = pdev->dev.of_node; enum of_gpio_flags flags; int ret; const char * strings = NULL; int value; if (!np) return -ENODEV; *mac = of_get_mac_address(np); plat->interface = of_get_phy_mode(np); plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); plat->init = stmmc_pltfr_init; plat->fix_mac_speed = stmmc_pltfr_fix_mac_speed; ret = of_property_read_string(np, "pmu_regulator", &strings); if (ret) { pr_err("%s: Can not read property: pmu_regulator.\n", __func__); g_bsp_priv.power_ctrl_by_pmu = false; } else { pr_info("%s: ethernet phy power controled by pmu(%s).\n", __func__, strings); g_bsp_priv.power_ctrl_by_pmu = true; strcpy(g_bsp_priv.pmu_regulator, strings); } ret = of_property_read_u32(np, "pmu_enable_level", &value); if (ret) { pr_err("%s: Can not read property: pmu_enable_level.\n", __func__); g_bsp_priv.power_ctrl_by_pmu = false; } else { pr_info("%s: ethernet phy power controled by pmu(level = %s).\n", __func__, (value == 1)?"HIGH":"LOW"); g_bsp_priv.power_ctrl_by_pmu = true; g_bsp_priv.pmu_enable_level = value; } ret = of_property_read_string(np, "clock_in_out", &strings); if (ret) { pr_err("%s: Can not read property: clock_in_out.\n", __func__); g_bsp_priv.clock_input = true; } else { pr_info("%s: clock input or output? (%s).\n", __func__, strings); if (!strcmp(strings, "input")) { g_bsp_priv.clock_input = true; } else { g_bsp_priv.clock_input = false; } } ret = of_property_read_u32(np, "tx_delay", &value); if (ret) { g_bsp_priv.tx_delay = 0x30; pr_err("%s: Can not read property: tx_delay. set tx_delay to 0x%x\n", __func__, g_bsp_priv.tx_delay); } else { pr_info("%s: TX delay(0x%x).\n", __func__, value); g_bsp_priv.tx_delay = value; } ret = of_property_read_u32(np, "rx_delay", &value); if (ret) { g_bsp_priv.rx_delay = 0x10; pr_err("%s: Can not read property: rx_delay. set rx_delay to 0x%x\n", __func__, g_bsp_priv.rx_delay); } else { pr_info("%s: RX delay(0x%x).\n", __func__, value); g_bsp_priv.rx_delay = value; } g_bsp_priv.reset_io = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); g_bsp_priv.reset_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; g_bsp_priv.power_io = of_get_named_gpio_flags(np, "power-gpio", 0, &flags); g_bsp_priv.power_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; g_bsp_priv.phy_iface = plat->interface; g_bsp_priv.phy_power_on = phy_power_on; g_bsp_priv.gmac_clk_enable = gmac_clk_enable; plat->bsp_priv = &g_bsp_priv; /* * Currently only the properties needed on SPEAr600 * are provided. All other properties should be added * once needed on other platforms. */ if (of_device_is_compatible(np, "rockchip,rk3288-gmac") || of_device_is_compatible(np, "rockchip,rk312x-gmac")) { plat->has_gmac = 1; plat->pmt = 1; } if (of_device_is_compatible(np, "rockchip,rk3288-gmac")) { g_bsp_priv.chip = RK3288_GMAC; printk("%s: is rockchip,rk3288-gmac", __func__); } if (of_device_is_compatible(np, "rockchip,rk312x-gmac")) { g_bsp_priv.chip = RK312X_GMAC; printk("%s: is rockchip,rk312x-gmac", __func__); } return 0; }
static int sun4i_ts_probe(struct platform_device *pdev) { struct sun4i_ts_data *ts; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct device *hwmon; int error; u32 reg; bool ts_attached; u32 tp_sensitive_adjust = 15; u32 filter_type = 1; ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); if (!ts) return -ENOMEM; ts->dev = dev; ts->ignore_fifo_data = true; ts->temp_data = -1; if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) { /* Allwinner SDK has temperature (C) = (value / 6) - 271 */ ts->temp_offset = 271000; ts->temp_step = 167; } else if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) { /* * The A10 temperature sensor has quite a wide spread, these * parameters are based on the averaging of the calibration * results of 4 completely different boards, with a spread of * temp_step from 0.096 - 0.170 and temp_offset from 176 - 331. */ ts->temp_offset = 257000; ts->temp_step = 133; } else { /* * The user manuals do not contain the formula for calculating * the temperature. The formula used here is from the AXP209, * which is designed by X-Powers, an affiliate of Allwinner: * * temperature (C) = (value * 0.1) - 144.7 * * Allwinner does not have any documentation whatsoever for * this hardware. Moreover, it is claimed that the sensor * is inaccurate and cannot work properly. */ ts->temp_offset = 144700; ts->temp_step = 100; } ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); if (ts_attached) { ts->input = devm_input_allocate_device(dev); if (!ts->input) return -ENOMEM; ts->input->name = pdev->name; ts->input->phys = "sun4i_ts/input0"; ts->input->open = sun4i_ts_open; ts->input->close = sun4i_ts_close; ts->input->id.bustype = BUS_HOST; ts->input->id.vendor = 0x0001; ts->input->id.product = 0x0001; ts->input->id.version = 0x0100; ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); __set_bit(BTN_TOUCH, ts->input->keybit); input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); input_set_drvdata(ts->input, ts); } ts->base = devm_ioremap_resource(dev, platform_get_resource(pdev, IORESOURCE_MEM, 0)); if (IS_ERR(ts->base)) return PTR_ERR(ts->base); ts->irq = platform_get_irq(pdev, 0); error = devm_request_irq(dev, ts->irq, sun4i_ts_irq, 0, "sun4i-ts", ts); if (error) return error; /* * Select HOSC clk, clkin = clk / 6, adc samplefreq = clkin / 8192, * t_acq = clkin / (16 * 64) */ writel(ADC_CLK_SEL(0) | ADC_CLK_DIV(2) | FS_DIV(7) | T_ACQ(63), ts->base + TP_CTRL0); /* * tp_sensitive_adjust is an optional property * tp_mode = 0 : only x and y coordinates, as we don't use dual touch */ of_property_read_u32(np, "allwinner,tp-sensitive-adjust", &tp_sensitive_adjust); writel(TP_SENSITIVE_ADJUST(tp_sensitive_adjust) | TP_MODE_SELECT(0), ts->base + TP_CTRL2); /* * Enable median and averaging filter, optional property for * filter type. */ of_property_read_u32(np, "allwinner,filter-type", &filter_type); writel(FILTER_EN(1) | FILTER_TYPE(filter_type), ts->base + TP_CTRL3); /* Enable temperature measurement, period 1953 (2 seconds) */ writel(TEMP_ENABLE(1) | TEMP_PERIOD(1953), ts->base + TP_TPR); /* * Set stylus up debounce to aprox 10 ms, enable debounce, and * finally enable tp mode. */ reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1); if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) reg |= SUN6I_TP_MODE_EN(1); else reg |= TP_MODE_EN(1); writel(reg, ts->base + TP_CTRL1); /* * The thermal core does not register hwmon devices for DT-based * thermal zone sensors, such as this one. */ hwmon = devm_hwmon_device_register_with_groups(ts->dev, "sun4i_ts", ts, sun4i_ts_groups); if (IS_ERR(hwmon)) return PTR_ERR(hwmon); devm_thermal_zone_of_sensor_register(ts->dev, 0, ts, &sun4i_ts_tz_ops); writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); if (ts_attached) { error = input_register_device(ts->input); if (error) { writel(0, ts->base + TP_INT_FIFOC); return error; } } platform_set_drvdata(pdev, ts); return 0; }
static int olpc_battery_probe(struct platform_device *pdev) { struct power_supply_config bat_psy_cfg = {}; struct power_supply_config ac_psy_cfg = {}; struct olpc_battery_data *data; uint8_t status; uint8_t ecver; int ret; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; platform_set_drvdata(pdev, data); /* See if the EC is already there and get the EC revision */ ret = olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, &ecver, 1); if (ret) return ret; if (of_find_compatible_node(NULL, NULL, "olpc,xo1.75-ec")) { /* XO 1.75 */ data->new_proto = true; data->little_endian = true; } else if (ecver > 0x44) { /* XO 1 or 1.5 with a new EC firmware. */ data->new_proto = true; } else if (ecver < 0x44) { /* * We've seen a number of EC protocol changes; this driver * requires the latest EC protocol, supported by 0x44 and above. */ printk(KERN_NOTICE "OLPC EC version 0x%02x too old for " "battery driver.\n", ecver); return -ENXIO; } ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1); if (ret) return ret; /* Ignore the status. It doesn't actually matter */ ac_psy_cfg.of_node = pdev->dev.of_node; ac_psy_cfg.drv_data = data; data->olpc_ac = devm_power_supply_register(&pdev->dev, &olpc_ac_desc, &ac_psy_cfg); if (IS_ERR(data->olpc_ac)) return PTR_ERR(data->olpc_ac); if (of_device_is_compatible(pdev->dev.of_node, "olpc,xo1.5-battery")) { /* XO-1.5 */ olpc_bat_desc.properties = olpc_xo15_bat_props; olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); } else { /* XO-1 */ olpc_bat_desc.properties = olpc_xo1_bat_props; olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); } bat_psy_cfg.of_node = pdev->dev.of_node; bat_psy_cfg.drv_data = data; bat_psy_cfg.attr_grp = olpc_bat_sysfs_groups; data->olpc_bat = devm_power_supply_register(&pdev->dev, &olpc_bat_desc, &bat_psy_cfg); if (IS_ERR(data->olpc_bat)) return PTR_ERR(data->olpc_bat); if (olpc_ec_wakeup_available()) { device_set_wakeup_capable(&data->olpc_ac->dev, true); device_set_wakeup_capable(&data->olpc_bat->dev, true); } return 0; }
static int __devinit ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; struct ohci_hcd *ohci; struct resource res; int irq; int rv; int is_bigendian; struct device_node *np; if (usb_disabled()) return -ENODEV; is_bigendian = of_device_is_compatible(dn, "ohci-bigendian") || of_device_is_compatible(dn, "ohci-be"); dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n"); rv = of_address_to_resource(dn, 0, &res); if (rv) return rv; hcd = usb_create_hcd(&ohci_ppc_of_hc_driver, &op->dev, "PPC-OF USB"); if (!hcd) return -ENOMEM; hcd->rsrc_start = res.start; hcd->rsrc_len = res.end - res.start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); rv = -EBUSY; goto err_rmr; } irq = irq_of_parse_and_map(dn, 0); if (irq == NO_IRQ) { printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); rv = -EBUSY; goto err_irq; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { printk(KERN_ERR "%s: ioremap failed\n", __FILE__); rv = -ENOMEM; goto err_ioremap; } ohci = hcd_to_ohci(hcd); if (is_bigendian) { ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; if (of_device_is_compatible(dn, "fsl,mpc5200-ohci")) ohci->flags |= OHCI_QUIRK_FRAME_NO; if (of_device_is_compatible(dn, "mpc5200-ohci")) ohci->flags |= OHCI_QUIRK_FRAME_NO; } ohci_hcd_init(ohci); rv = usb_add_hcd(hcd, irq, IRQF_DISABLED); if (rv == 0) return 0; /* by now, 440epx is known to show usb_23 erratum */ np = of_find_compatible_node(NULL, NULL, "ibm,usb-ehci-440epx"); /* Work around - At this point ohci_run has executed, the * controller is running, everything, the root ports, etc., is * set up. If the ehci driver is loaded, put the ohci core in * the suspended state. The ehci driver will bring it out of * suspended state when / if a non-high speed USB device is * attached to the USB Host port. If the ehci driver is not * loaded, do nothing. request_mem_region is used to test if * the ehci driver is loaded. */ if (np != NULL) { if (!of_address_to_resource(np, 0, &res)) { if (!request_mem_region(res.start, 0x4, hcd_name)) { writel_be((readl_be(&ohci->regs->control) | OHCI_USB_SUSPEND), &ohci->regs->control); (void) readl_be(&ohci->regs->control); } else release_mem_region(res.start, 0x4); } else pr_debug("%s: cannot get ehci offset from fdt\n", __FILE__); } iounmap(hcd->regs); err_ioremap: irq_dispose_mapping(irq); err_irq: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_rmr: usb_put_hcd(hcd); return rv; }
static int msm_ispif_init(struct ispif_device *ispif, uint32_t csid_version) { int rc = 0; BUG_ON(!ispif); if (ispif->ispif_state == ISPIF_POWER_UP) { pr_err("%s: ispif already initted state = %d\n", __func__, ispif->ispif_state); rc = -EPERM; return rc; } /* can we set to zero? */ ispif->applied_intf_cmd[VFE0].intf_cmd = 0xFFFFFFFF; ispif->applied_intf_cmd[VFE0].intf_cmd1 = 0xFFFFFFFF; ispif->applied_intf_cmd[VFE1].intf_cmd = 0xFFFFFFFF; ispif->applied_intf_cmd[VFE1].intf_cmd1 = 0xFFFFFFFF; memset(ispif->sof_count, 0, sizeof(ispif->sof_count)); ispif->csid_version = csid_version; if (ispif->csid_version >= CSID_VERSION_V30) { if (!ispif->clk_mux_mem || !ispif->clk_mux_io) { pr_err("%s csi clk mux mem %p io %p\n", __func__, ispif->clk_mux_mem, ispif->clk_mux_io); rc = -ENOMEM; return rc; } ispif->clk_mux_base = ioremap(ispif->clk_mux_mem->start, resource_size(ispif->clk_mux_mem)); if (!ispif->clk_mux_base) { pr_err("%s: clk_mux_mem ioremap failed\n", __func__); rc = -ENOMEM; return rc; } } ispif->base = ioremap(ispif->mem->start, resource_size(ispif->mem)); if (!ispif->base) { rc = -ENOMEM; pr_err("%s: nomem\n", __func__); goto end; } rc = request_irq(ispif->irq->start, msm_io_ispif_irq, IRQF_TRIGGER_RISING, "ispif", ispif); if (rc) { pr_err("%s: request_irq error = %d\n", __func__, rc); goto error_irq; } rc = msm_ispif_clk_ahb_enable(ispif, 1); if (rc) { pr_err("%s: ahb_clk enable failed", __func__); goto error_ahb; } if (of_device_is_compatible(ispif->pdev->dev.of_node, "qcom,ispif-v3.0")) { /* currently HW reset is implemented for 8974 only */ msm_ispif_reset_hw(ispif); } rc = msm_ispif_reset(ispif); if (rc == 0) { ispif->ispif_state = ISPIF_POWER_UP; CDBG("%s: power up done\n", __func__); goto end; } error_ahb: free_irq(ispif->irq->start, ispif); error_irq: iounmap(ispif->base); end: return rc; }
static int dw_mmc_probe(struct device_d *dev) { struct resource *iores; struct dwmci_host *host; struct dw_mmc_platform_data *pdata = dev->platform_data; host = xzalloc(sizeof(*host)); host->clk_biu = clk_get(dev, "biu"); if (IS_ERR(host->clk_biu)) return PTR_ERR(host->clk_biu); host->clk_ciu = clk_get(dev, "ciu"); if (IS_ERR(host->clk_ciu)) return PTR_ERR(host->clk_ciu); clk_enable(host->clk_biu); clk_enable(host->clk_ciu); host->dev = dev; iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) return PTR_ERR(iores); host->ioaddr = IOMEM(iores->start); host->idmac = dma_alloc_coherent(sizeof(*host->idmac) * DW_MMC_NUM_IDMACS, DMA_ADDRESS_BROKEN); host->mci.send_cmd = dwmci_cmd; host->mci.set_ios = dwmci_set_ios; host->mci.init = dwmci_init; host->mci.card_present = dwmci_card_present; host->mci.hw_dev = dev; host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; host->mci.host_caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; host->mci.host_caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED_52MHZ | MMC_CAP_SD_HIGHSPEED; if (pdata) { host->ciu_div = pdata->ciu_div; host->mci.host_caps &= ~MMC_CAP_BIT_DATA_MASK; host->mci.host_caps |= pdata->bus_width_caps; } else if (dev->device_node) { const char *alias = of_alias_get(dev->device_node); if (alias) host->mci.devname = xstrdup(alias); of_property_read_u32(dev->device_node, "dw-mshc-ciu-div", &host->ciu_div); } /* divider is 0 based in pdata and 1 based in our private struct */ host->ciu_div++; if (of_device_is_compatible(dev->device_node, "rockchip,rk2928-dw-mshc")) host->pwren_value = 0; else host->pwren_value = 1; dev->detect = dw_mmc_detect; host->clkrate = clk_get_rate(host->clk_ciu); host->mci.f_min = host->clkrate / 510 / host->ciu_div; if (host->mci.f_min < 200000) host->mci.f_min = 200000; host->mci.f_max = host->clkrate / host->ciu_div; mci_of_parse(&host->mci); dev->priv = host; return mci_register(&host->mci); }
void __init opal_sys_param_init(void) { struct device_node *sysparam; struct param_attr *attr; u32 *id, *size; int count, i; u8 *perm; if (!opal_kobj) { pr_warn("SYSPARAM: opal kobject is not available\n"); goto out; } sysparam_kobj = kobject_create_and_add("sysparams", opal_kobj); if (!sysparam_kobj) { pr_err("SYSPARAM: Failed to create sysparam kobject\n"); goto out; } /* Allocate big enough buffer for any get/set transactions */ param_data_buf = kzalloc(MAX_PARAM_DATA_LEN, GFP_KERNEL); if (!param_data_buf) { pr_err("SYSPARAM: Failed to allocate memory for param data " "buf\n"); goto out_kobj_put; } sysparam = of_find_node_by_path("/ibm,opal/sysparams"); if (!sysparam) { pr_err("SYSPARAM: Opal sysparam node not found\n"); goto out_param_buf; } if (!of_device_is_compatible(sysparam, "ibm,opal-sysparams")) { pr_err("SYSPARAM: Opal sysparam node not compatible\n"); goto out_node_put; } /* Number of parameters exposed through DT */ count = of_property_count_strings(sysparam, "param-name"); if (count < 0) { pr_err("SYSPARAM: No string found of property param-name in " "the node %s\n", sysparam->name); goto out_node_put; } id = kzalloc(sizeof(*id) * count, GFP_KERNEL); if (!id) { pr_err("SYSPARAM: Failed to allocate memory to read parameter " "id\n"); goto out_node_put; } size = kzalloc(sizeof(*size) * count, GFP_KERNEL); if (!size) { pr_err("SYSPARAM: Failed to allocate memory to read parameter " "size\n"); goto out_free_id; } perm = kzalloc(sizeof(*perm) * count, GFP_KERNEL); if (!perm) { pr_err("SYSPARAM: Failed to allocate memory to read supported " "action on the parameter"); goto out_free_size; } if (of_property_read_u32_array(sysparam, "param-id", id, count)) { pr_err("SYSPARAM: Missing property param-id in the DT\n"); goto out_free_perm; } if (of_property_read_u32_array(sysparam, "param-len", size, count)) { pr_err("SYSPARAM: Missing propery param-len in the DT\n"); goto out_free_perm; } if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) { pr_err("SYSPARAM: Missing propery param-perm in the DT\n"); goto out_free_perm; } attr = kzalloc(sizeof(*attr) * count, GFP_KERNEL); if (!attr) { pr_err("SYSPARAM: Failed to allocate memory for parameter " "attributes\n"); goto out_free_perm; } /* For each of the parameters, populate the parameter attributes */ for (i = 0; i < count; i++) { sysfs_attr_init(&attr[i].kobj_attr.attr); attr[i].param_id = id[i]; attr[i].param_size = size[i]; if (of_property_read_string_index(sysparam, "param-name", i, &attr[i].kobj_attr.attr.name)) continue; /* If the parameter is read-only or read-write */ switch (perm[i] & 3) { case OPAL_SYSPARAM_READ: attr[i].kobj_attr.attr.mode = S_IRUGO; break; case OPAL_SYSPARAM_WRITE: attr[i].kobj_attr.attr.mode = S_IWUGO; break; case OPAL_SYSPARAM_RW: attr[i].kobj_attr.attr.mode = S_IRUGO | S_IWUGO; break; default: break; } attr[i].kobj_attr.show = sys_param_show; attr[i].kobj_attr.store = sys_param_store; if (sysfs_create_file(sysparam_kobj, &attr[i].kobj_attr.attr)) { pr_err("SYSPARAM: Failed to create sysfs file %s\n", attr[i].kobj_attr.attr.name); goto out_free_attr; } } kfree(perm); kfree(size); kfree(id); of_node_put(sysparam); return; out_free_attr: kfree(attr); out_free_perm: kfree(perm); out_free_size: kfree(size); out_free_id: kfree(id); out_node_put: of_node_put(sysparam); out_param_buf: kfree(param_data_buf); out_kobj_put: kobject_put(sysparam_kobj); out: return; }
static void __init mpc8xxx_add_controller(struct device_node *np) { struct mpc8xxx_gpio_chip *mpc8xxx_gc; struct of_mm_gpio_chip *mm_gc; struct gpio_chip *gc; const struct of_device_id *id; unsigned hwirq; int ret; mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); if (!mpc8xxx_gc) { ret = -ENOMEM; goto err; } spin_lock_init(&mpc8xxx_gc->lock); mm_gc = &mpc8xxx_gc->mm_gc; gc = &mm_gc->gc; mm_gc->save_regs = mpc8xxx_gpio_save_regs; gc->ngpio = MPC8XXX_GPIO_PINS; gc->direction_input = mpc8xxx_gpio_dir_in; gc->direction_output = of_device_is_compatible(np, "fsl,mpc5121-gpio") ? mpc5121_gpio_dir_out : mpc8xxx_gpio_dir_out; gc->get = of_device_is_compatible(np, "fsl,mpc8572-gpio") ? mpc8572_gpio_get : mpc8xxx_gpio_get; gc->set = mpc8xxx_gpio_set; gc->to_irq = mpc8xxx_gpio_to_irq; ret = of_mm_gpiochip_add(np, mm_gc); if (ret) goto err; hwirq = irq_of_parse_and_map(np, 0); if (hwirq == NO_IRQ) goto skip_irq; mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS, &mpc8xxx_gpio_irq_ops, mpc8xxx_gc); if (!mpc8xxx_gc->irq) goto skip_irq; id = of_match_node(mpc8xxx_gpio_ids, np); if (id) mpc8xxx_gc->of_dev_id_data = id->data; /* ack and mask all irqs */ out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); out_be32(mm_gc->regs + GPIO_IMR, 0); irq_set_handler_data(hwirq, mpc8xxx_gc); irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); skip_irq: return; err: pr_err("%s: registration failed with status %d\n", np->full_name, ret); kfree(mpc8xxx_gc); return; }
static int __init cpm_uart_console_setup(struct console *co, char *options) { int baud = 38400; int bits = 8; int parity = 'n'; int flow = 'n'; int ret; struct uart_cpm_port *pinfo; struct uart_port *port; struct device_node *np = NULL; int i = 0; if (co->index >= UART_NR) { printk(KERN_ERR "cpm_uart: console index %d too high\n", co->index); return -ENODEV; } do { np = of_find_node_by_type(np, "serial"); if (!np) return -ENODEV; if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") && !of_device_is_compatible(np, "fsl,cpm1-scc-uart") && !of_device_is_compatible(np, "fsl,cpm2-smc-uart") && !of_device_is_compatible(np, "fsl,cpm2-scc-uart")) i--; } while (i++ != co->index); pinfo = &cpm_uart_ports[co->index]; pinfo->flags |= FLAG_CONSOLE; port = &pinfo->port; ret = cpm_uart_init_port(np, pinfo); of_node_put(np); if (ret) return ret; if (options) { uart_parse_options(options, &baud, &parity, &bits, &flow); } else { if ((baud = uart_baudrate()) == -1) baud = 9600; } #ifdef CONFIG_PPC_EARLY_DEBUG_CPM udbg_putc = NULL; #endif if (IS_SMC(pinfo)) { out_be16(&pinfo->smcup->smc_brkcr, 0); cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); } else { out_be16(&pinfo->sccup->scc_brkcr, 0); cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); } ret = cpm_uart_allocbuf(pinfo, 1); if (ret) return ret; cpm_uart_initbd(pinfo); if (IS_SMC(pinfo)) cpm_uart_init_smc(pinfo); else cpm_uart_init_scc(pinfo); uart_set_options(port, co, baud, parity, bits, flow); cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); return 0; }
static int dw8250_probe_of(struct uart_port *p, struct dw8250_data *data) { struct device_node *np = p->dev->of_node; struct uart_8250_port *up = up_to_u8250p(p); u32 val; bool has_ucv = true; int id; #ifdef CONFIG_64BIT if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) { p->serial_in = dw8250_serial_inq; p->serial_out = dw8250_serial_outq; p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; p->type = PORT_OCTEON; data->usr_reg = 0x27; has_ucv = false; } else #endif if (!of_property_read_u32(np, "reg-io-width", &val)) { switch (val) { case 1: break; case 4: p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; break; default: dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); return -EINVAL; } } if (has_ucv) dw8250_setup_port(up); /* if we have a valid fifosize, try hooking up DMA here */ if (p->fifosize) { up->dma = &data->dma; up->dma->rxconf.src_maxburst = p->fifosize / 4; up->dma->txconf.dst_maxburst = p->fifosize / 4; } if (!of_property_read_u32(np, "reg-shift", &val)) p->regshift = val; /* get index of serial line, if found in DT aliases */ id = of_alias_get_id(np, "serial"); if (id >= 0) p->line = id; if (of_property_read_bool(np, "dcd-override")) { /* Always report DCD as active */ data->msr_mask_on |= UART_MSR_DCD; data->msr_mask_off |= UART_MSR_DDCD; } if (of_property_read_bool(np, "dsr-override")) { /* Always report DSR as active */ data->msr_mask_on |= UART_MSR_DSR; data->msr_mask_off |= UART_MSR_DDSR; } if (of_property_read_bool(np, "cts-override")) { /* Always report CTS as active */ data->msr_mask_on |= UART_MSR_CTS; data->msr_mask_off |= UART_MSR_DCTS; } if (of_property_read_bool(np, "ri-override")) { /* Always report Ring indicator as inactive */ data->msr_mask_off |= UART_MSR_RI; data->msr_mask_off |= UART_MSR_TERI; } return 0; }
static void of_gpio_flags_quirks(struct device_node *np, const char *propname, enum of_gpio_flags *flags, int index) { /* * Handle MMC "cd-inverted" and "wp-inverted" semantics. */ if (IS_ENABLED(CONFIG_MMC)) { /* * Active low is the default according to the * SDHCI specification and the device tree * bindings. However the code in the current * kernel was written such that the phandle * flags were always respected, and "cd-inverted" * would invert the flag from the device phandle. */ if (!strcmp(propname, "cd-gpios")) { if (of_property_read_bool(np, "cd-inverted")) *flags ^= OF_GPIO_ACTIVE_LOW; } if (!strcmp(propname, "wp-gpios")) { if (of_property_read_bool(np, "wp-inverted")) *flags ^= OF_GPIO_ACTIVE_LOW; } } /* * Some GPIO fixed regulator quirks. * Note that active low is the default. */ if (IS_ENABLED(CONFIG_REGULATOR) && (of_device_is_compatible(np, "regulator-fixed") || of_device_is_compatible(np, "reg-fixed-voltage") || (of_device_is_compatible(np, "regulator-gpio") && !(strcmp(propname, "enable-gpio") && strcmp(propname, "enable-gpios"))))) { /* * The regulator GPIO handles are specified such that the * presence or absence of "enable-active-high" solely controls * the polarity of the GPIO line. Any phandle flags must * be actively ignored. */ if (*flags & OF_GPIO_ACTIVE_LOW) { pr_warn("%s GPIO handle specifies active low - ignored\n", of_node_full_name(np)); *flags &= ~OF_GPIO_ACTIVE_LOW; } if (!of_property_read_bool(np, "enable-active-high")) *flags |= OF_GPIO_ACTIVE_LOW; } /* * Legacy open drain handling for fixed voltage regulators. */ if (IS_ENABLED(CONFIG_REGULATOR) && of_device_is_compatible(np, "reg-fixed-voltage") && of_property_read_bool(np, "gpio-open-drain")) { *flags |= (OF_GPIO_SINGLE_ENDED | OF_GPIO_OPEN_DRAIN); pr_info("%s uses legacy open drain flag - update the DTS if you can\n", of_node_full_name(np)); } /* * Legacy handling of SPI active high chip select. If we have a * property named "cs-gpios" we need to inspect the child node * to determine if the flags should have inverted semantics. */ if (IS_ENABLED(CONFIG_SPI_MASTER) && of_property_read_bool(np, "cs-gpios")) { struct device_node *child; u32 cs; int ret; for_each_child_of_node(np, child) { ret = of_property_read_u32(child, "reg", &cs); if (ret) continue; if (cs == index) { /* * SPI children have active low chip selects * by default. This can be specified negatively * by just omitting "spi-cs-high" in the * device node, or actively by tagging on * GPIO_ACTIVE_LOW as flag in the device * tree. If the line is simultaneously * tagged as active low in the device tree * and has the "spi-cs-high" set, we get a * conflict and the "spi-cs-high" flag will * take precedence. */ if (of_property_read_bool(np, "spi-cs-high")) { if (*flags & OF_GPIO_ACTIVE_LOW) { pr_warn("%s GPIO handle specifies active low - ignored\n", of_node_full_name(np)); *flags &= ~OF_GPIO_ACTIVE_LOW; } } else { if (!(*flags & OF_GPIO_ACTIVE_LOW)) pr_info("%s enforce active low on chipselect handle\n", of_node_full_name(np)); *flags |= OF_GPIO_ACTIVE_LOW; } break; } } }
/* * Setup one port structure after probing, HW is down at this point, * Unlike sunzilog, we don't need to pre-init the spinlock as we don't * register our console before uart_add_one_port() is called */ static int __init pmz_init_port(struct uart_pmac_port *uap) { struct device_node *np = uap->node; const char *conn; const struct slot_names_prop { int count; char name[1]; } *slots; int len; struct resource r_ports, r_rxdma, r_txdma; /* * Request & map chip registers */ if (of_address_to_resource(np, 0, &r_ports)) return -ENODEV; uap->port.mapbase = r_ports.start; uap->port.membase = ioremap(uap->port.mapbase, 0x1000); uap->control_reg = uap->port.membase; uap->data_reg = uap->control_reg + 0x10; /* * Request & map DBDMA registers */ #ifdef HAS_DBDMA if (of_address_to_resource(np, 1, &r_txdma) == 0 && of_address_to_resource(np, 2, &r_rxdma) == 0) uap->flags |= PMACZILOG_FLAG_HAS_DMA; #else memset(&r_txdma, 0, sizeof(struct resource)); memset(&r_rxdma, 0, sizeof(struct resource)); #endif if (ZS_HAS_DMA(uap)) { uap->tx_dma_regs = ioremap(r_txdma.start, 0x100); if (uap->tx_dma_regs == NULL) { uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100); if (uap->rx_dma_regs == NULL) { iounmap(uap->tx_dma_regs); uap->tx_dma_regs = NULL; uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } uap->tx_dma_irq = irq_of_parse_and_map(np, 1); uap->rx_dma_irq = irq_of_parse_and_map(np, 2); } no_dma: /* * Detect port type */ if (of_device_is_compatible(np, "cobalt")) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; conn = of_get_property(np, "AAPL,connector", &len); if (conn && (strcmp(conn, "infrared") == 0)) uap->flags |= PMACZILOG_FLAG_IS_IRDA; uap->port_type = PMAC_SCC_ASYNC; /* 1999 Powerbook G3 has slot-names property instead */ slots = of_get_property(np, "slot-names", &len); if (slots && slots->count > 0) { if (strcmp(slots->name, "IrDA") == 0) uap->flags |= PMACZILOG_FLAG_IS_IRDA; else if (strcmp(slots->name, "Modem") == 0) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; } if (ZS_IS_IRDA(uap)) uap->port_type = PMAC_SCC_IRDA; if (ZS_IS_INTMODEM(uap)) { struct device_node* i2c_modem = of_find_node_by_name(NULL, "i2c-modem"); if (i2c_modem) { const char* mid = of_get_property(i2c_modem, "modem-id", NULL); if (mid) switch(*mid) { case 0x04 : case 0x05 : case 0x07 : case 0x08 : case 0x0b : case 0x0c : uap->port_type = PMAC_SCC_I2S1; } printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n", mid ? (*mid) : 0); of_node_put(i2c_modem); } else { printk(KERN_INFO "pmac_zilog: serial modem detected\n"); } } /* * Init remaining bits of "port" structure */ uap->port.iotype = UPIO_MEM; uap->port.irq = irq_of_parse_and_map(np, 0); uap->port.uartclk = ZS_CLOCK; uap->port.fifosize = 1; uap->port.ops = &pmz_pops; uap->port.type = PORT_PMAC_ZILOG; uap->port.flags = 0; /* Setup some valid baud rate information in the register * shadows so we don't write crap there before baud rate is * first initialized. */ pmz_convert_to_zs(uap, CS8, 0, 9600); return 0; }
static int fsl_asoc_card_probe(struct platform_device *pdev) { struct device_node *cpu_np, *codec_np, *asrc_np; struct device_node *np = pdev->dev.of_node; struct platform_device *asrc_pdev = NULL; struct platform_device *cpu_pdev; struct fsl_asoc_card_priv *priv; struct i2c_client *codec_dev; const char *codec_dai_name; u32 width; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; cpu_np = of_parse_phandle(np, "audio-cpu", 0); /* Give a chance to old DT binding */ if (!cpu_np) cpu_np = of_parse_phandle(np, "ssi-controller", 0); if (!cpu_np) { dev_err(&pdev->dev, "CPU phandle missing or invalid\n"); ret = -EINVAL; goto fail; } cpu_pdev = of_find_device_by_node(cpu_np); if (!cpu_pdev) { dev_err(&pdev->dev, "failed to find CPU DAI device\n"); ret = -EINVAL; goto fail; } codec_np = of_parse_phandle(np, "audio-codec", 0); if (codec_np) codec_dev = of_find_i2c_device_by_node(codec_np); else codec_dev = NULL; asrc_np = of_parse_phandle(np, "audio-asrc", 0); if (asrc_np) asrc_pdev = of_find_device_by_node(asrc_np); /* Get the MCLK rate only, and leave it controlled by CODEC drivers */ if (codec_dev) { struct clk *codec_clk = clk_get(&codec_dev->dev, NULL); if (!IS_ERR(codec_clk)) { priv->codec_priv.mclk_freq = clk_get_rate(codec_clk); clk_put(codec_clk); } } /* Default sample rate and format, will be updated in hw_params() */ priv->sample_rate = 44100; priv->sample_format = SNDRV_PCM_FORMAT_S16_LE; /* Assign a default DAI format, and allow each card to overwrite it */ priv->dai_fmt = DAI_FMT_BASE; /* Diversify the card configurations */ if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) { codec_dai_name = "cs42888"; priv->card.set_bias_level = NULL; priv->cpu_priv.sysclk_freq[TX] = priv->codec_priv.mclk_freq; priv->cpu_priv.sysclk_freq[RX] = priv->codec_priv.mclk_freq; priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT; priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT; priv->cpu_priv.slot_width = 32; priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; } else if (of_device_is_compatible(np, "fsl,imx-audio-cs427x")) { codec_dai_name = "cs4271-hifi"; priv->codec_priv.mclk_id = CS427x_SYSCLK_MCLK; priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; } else if (of_device_is_compatible(np, "fsl,imx-audio-sgtl5000")) { codec_dai_name = "sgtl5000"; priv->codec_priv.mclk_id = SGTL5000_SYSCLK; priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8962")) { codec_dai_name = "wm8962"; priv->card.set_bias_level = fsl_asoc_card_set_bias_level; priv->codec_priv.mclk_id = WM8962_SYSCLK_MCLK; priv->codec_priv.fll_id = WM8962_SYSCLK_FLL; priv->codec_priv.pll_id = WM8962_FLL; priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8960")) { codec_dai_name = "wm8960-hifi"; priv->card.set_bias_level = fsl_asoc_card_set_bias_level; priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO; priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO; priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; } else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) { codec_dai_name = "ac97-hifi"; priv->card.set_bias_level = NULL; priv->dai_fmt = SND_SOC_DAIFMT_AC97; } else { dev_err(&pdev->dev, "unknown Device Tree compatible\n"); ret = -EINVAL; goto asrc_fail; } if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) { dev_err(&pdev->dev, "failed to find codec device\n"); ret = -EINVAL; goto asrc_fail; } /* Common settings for corresponding Freescale CPU DAI driver */ if (strstr(cpu_np->name, "ssi")) { /* Only SSI needs to configure AUDMUX */ ret = fsl_asoc_card_audmux_init(np, priv); if (ret) { dev_err(&pdev->dev, "failed to init audmux\n"); goto asrc_fail; } } else if (strstr(cpu_np->name, "esai")) { priv->cpu_priv.sysclk_id[1] = ESAI_HCKT_EXTAL; priv->cpu_priv.sysclk_id[0] = ESAI_HCKR_EXTAL; } else if (strstr(cpu_np->name, "sai")) { priv->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1; priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1; } snprintf(priv->name, sizeof(priv->name), "%s-audio", fsl_asoc_card_is_ac97(priv) ? "ac97" : codec_dev->name); /* Initialize sound card */ priv->pdev = pdev; priv->card.dev = &pdev->dev; priv->card.name = priv->name; priv->card.dai_link = priv->dai_link; priv->card.dapm_routes = fsl_asoc_card_is_ac97(priv) ? audio_map_ac97 : audio_map; priv->card.late_probe = fsl_asoc_card_late_probe; priv->card.num_dapm_routes = ARRAY_SIZE(audio_map); priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets; priv->card.num_dapm_widgets = ARRAY_SIZE(fsl_asoc_card_dapm_widgets); /* Drop the second half of DAPM routes -- ASRC */ if (!asrc_pdev) priv->card.num_dapm_routes /= 2; memcpy(priv->dai_link, fsl_asoc_card_dai, sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link)); ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing"); if (ret) { dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret); goto asrc_fail; } /* Normal DAI Link */ priv->dai_link[0].cpu_of_node = cpu_np; priv->dai_link[0].codec_dai_name = codec_dai_name; if (!fsl_asoc_card_is_ac97(priv)) priv->dai_link[0].codec_of_node = codec_np; else { u32 idx; ret = of_property_read_u32(cpu_np, "cell-index", &idx); if (ret) { dev_err(&pdev->dev, "cannot get CPU index property\n"); goto asrc_fail; } priv->dai_link[0].codec_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ac97-codec.%u", (unsigned int)idx); } priv->dai_link[0].platform_of_node = cpu_np; priv->dai_link[0].dai_fmt = priv->dai_fmt; priv->card.num_links = 1; if (asrc_pdev) { /* DPCM DAI Links only if ASRC exsits */ priv->dai_link[1].cpu_of_node = asrc_np; priv->dai_link[1].platform_of_node = asrc_np; priv->dai_link[2].codec_dai_name = codec_dai_name; priv->dai_link[2].codec_of_node = codec_np; priv->dai_link[2].codec_name = priv->dai_link[0].codec_name; priv->dai_link[2].cpu_of_node = cpu_np; priv->dai_link[2].dai_fmt = priv->dai_fmt; priv->card.num_links = 3; ret = of_property_read_u32(asrc_np, "fsl,asrc-rate", &priv->asrc_rate); if (ret) { dev_err(&pdev->dev, "failed to get output rate\n"); ret = -EINVAL; goto asrc_fail; } ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width); if (ret) { dev_err(&pdev->dev, "failed to get output rate\n"); ret = -EINVAL; goto asrc_fail; } if (width == 24) priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE; else priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE; } /* Finish card registering */ platform_set_drvdata(pdev, priv); snd_soc_card_set_drvdata(&priv->card, priv); ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); if (ret) dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); asrc_fail: of_node_put(asrc_np); of_node_put(codec_np); fail: of_node_put(cpu_np); return ret; }
static int __init add_legacy_pci_port(struct device_node *np, struct device_node *pci_dev) { u64 addr, base; const u32 *addrp; unsigned int flags; int iotype, index = -1, lindex = 0; DBG(" -> add_legacy_pci_port(%s)\n", np->full_name); /* We only support ports that have a clock frequency properly * encoded in the device-tree (that is have an fcode). Anything * else can't be used that early and will be normally probed by * the generic 8250_pci driver later on. The reason is that 8250 * compatible UARTs on PCI need all sort of quirks (port offsets * etc...) that this code doesn't know about */ if (of_get_property(np, "clock-frequency", NULL) == NULL) return -1; /* Get the PCI address. Assume BAR 0 */ addrp = of_get_pci_address(pci_dev, 0, NULL, &flags); if (addrp == NULL) return -1; /* We only support BAR 0 for now */ iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT; addr = of_translate_address(pci_dev, addrp); if (addr == OF_BAD_ADDR) return -1; /* Set the IO base to the same as the translated address for MMIO, * or to the domain local IO base for PIO (it will be fixed up later) */ if (iotype == UPIO_MEM) base = addr; else base = addrp[2]; /* Try to guess an index... If we have subdevices of the pci dev, * we get to their "reg" property */ if (np != pci_dev) { const u32 *reg = of_get_property(np, "reg", NULL); if (reg && (*reg < 4)) index = lindex = *reg; } /* Local index means it's the Nth port in the PCI chip. Unfortunately * the offset to add here is device specific. We know about those * EXAR ports and we default to the most common case. If your UART * doesn't work for these settings, you'll have to add your own special * cases here */ if (of_device_is_compatible(pci_dev, "pci13a8,152") || of_device_is_compatible(pci_dev, "pci13a8,154") || of_device_is_compatible(pci_dev, "pci13a8,158")) { addr += 0x200 * lindex; base += 0x200 * lindex; } else { addr += 8 * lindex; base += 8 * lindex; } /* Add port, irq will be dealt with later. We passed a translated * IO port value. It will be fixed up later along with the irq */ return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF, np != pci_dev); }
static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata( struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *tnp, *iter; struct tegra_emc_pdata *pdata; int ret, i, num_tables; if (!np) return NULL; if (of_find_property(np, "nvidia,use-ram-code", NULL)) { tnp = tegra_emc_ramcode_devnode(np); if (!tnp) dev_warn(&pdev->dev, "can't find emc table for ram-code 0x%02x\n", tegra_bct_strapping); } else tnp = of_node_get(np); if (!tnp) return NULL; num_tables = 0; for_each_child_of_node(tnp, iter) if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table")) num_tables++; if (!num_tables) { pdata = NULL; goto out; } pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); pdata->tables = devm_kzalloc(&pdev->dev, sizeof(*pdata->tables) * num_tables, GFP_KERNEL); i = 0; for_each_child_of_node(tnp, iter) { u32 prop; ret = of_property_read_u32(iter, "clock-frequency", &prop); if (ret) { dev_err(&pdev->dev, "no clock-frequency in %s\n", iter->full_name); continue; } pdata->tables[i].rate = prop; ret = of_property_read_u32_array(iter, "nvidia,emc-registers", pdata->tables[i].regs, TEGRA_EMC_NUM_REGS); if (ret) { dev_err(&pdev->dev, "malformed emc-registers property in %s\n", iter->full_name); continue; } i++; }
/* * This is called very early, as part of setup_system() or eventually * setup_arch(), basically before anything else in this file. This function * will try to build a list of all the available 8250-compatible serial ports * in the machine using the Open Firmware device-tree. It currently only deals * with ISA and PCI busses but could be extended. It allows a very early boot * console to be initialized, that list is also used later to provide 8250 with * the machine non-PCI ports and to properly pick the default console port */ void __init find_legacy_serial_ports(void) { struct device_node *np, *stdout = NULL; const char *path; int index; DBG(" -> find_legacy_serial_port()\n"); /* Now find out if one of these is out firmware console */ path = of_get_property(of_chosen, "linux,stdout-path", NULL); if (path != NULL) { stdout = of_find_node_by_path(path); if (stdout) DBG("stdout is %s\n", stdout->full_name); } else { DBG(" no linux,stdout-path !\n"); } /* First fill our array with SOC ports */ for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { struct device_node *soc = of_get_parent(np); if (soc && !strcmp(soc->type, "soc")) { index = add_legacy_soc_port(np, np); if (index >= 0 && np == stdout) legacy_serial_console = index; } of_node_put(soc); } /* First fill our array with ISA ports */ for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { struct device_node *isa = of_get_parent(np); if (isa && !strcmp(isa->name, "isa")) { index = add_legacy_isa_port(np, isa); if (index >= 0 && np == stdout) legacy_serial_console = index; } of_node_put(isa); } /* First fill our array with tsi-bridge ports */ for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { struct device_node *tsi = of_get_parent(np); if (tsi && !strcmp(tsi->type, "tsi-bridge")) { index = add_legacy_soc_port(np, np); if (index >= 0 && np == stdout) legacy_serial_console = index; } of_node_put(tsi); } /* First fill our array with opb bus ports */ for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16750")) != NULL;) { struct device_node *opb = of_get_parent(np); if (opb && !strcmp(opb->type, "opb")) { index = add_legacy_soc_port(np, np); if (index >= 0 && np == stdout) legacy_serial_console = index; } of_node_put(opb); } #ifdef CONFIG_PCI /* Next, try to locate PCI ports */ for (np = NULL; (np = of_find_all_nodes(np));) { struct device_node *pci, *parent = of_get_parent(np); if (parent && !strcmp(parent->name, "isa")) { of_node_put(parent); continue; } if (strcmp(np->name, "serial") && strcmp(np->type, "serial")) { of_node_put(parent); continue; } /* Check for known pciclass, and also check wether we have * a device with child nodes for ports or not */ if (of_device_is_compatible(np, "pciclass,0700") || of_device_is_compatible(np, "pciclass,070002")) pci = np; else if (of_device_is_compatible(parent, "pciclass,0700") || of_device_is_compatible(parent, "pciclass,070002")) pci = parent; else { of_node_put(parent); continue; } index = add_legacy_pci_port(np, pci); if (index >= 0 && np == stdout) legacy_serial_console = index; of_node_put(parent); } #endif DBG("legacy_serial_console = %d\n", legacy_serial_console); if (legacy_serial_console >= 0) setup_legacy_serial_console(legacy_serial_console); DBG(" <- find_legacy_serial_port()\n"); }
static int __init tsi108_eth_of_init(void) { struct device_node *np; unsigned int i; struct platform_device *tsi_eth_dev; struct resource res; int ret; for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL; i++) { struct resource r[2]; struct device_node *phy; hw_info tsi_eth_data; const unsigned int *id; const unsigned int *phy_id; const void *mac_addr; const phandle *ph; memset(r, 0, sizeof(r)); memset(&tsi_eth_data, 0, sizeof(tsi_eth_data)); ret = of_address_to_resource(np, 0, &r[0]); DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", __FUNCTION__,r[0].name, r[0].start, r[0].end); if (ret) goto err; r[1].name = "tx"; r[1].start = irq_of_parse_and_map(np, 0); r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", __FUNCTION__,r[1].name, r[1].start, r[1].end); tsi_eth_dev = platform_device_register_simple("tsi-ethernet", i, &r[0], 1); if (IS_ERR(tsi_eth_dev)) { ret = PTR_ERR(tsi_eth_dev); goto err; } mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(tsi_eth_data.mac_addr, mac_addr, 6); ph = of_get_property(np, "phy-handle", NULL); phy = of_find_node_by_phandle(*ph); if (phy == NULL) { ret = -ENODEV; goto unreg; } id = of_get_property(phy, "reg", NULL); phy_id = of_get_property(phy, "phy-id", NULL); ret = of_address_to_resource(phy, 0, &res); if (ret) { of_node_put(phy); goto unreg; } tsi_eth_data.regs = r[0].start; tsi_eth_data.phyregs = res.start; tsi_eth_data.phy = *phy_id; tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0); if (of_device_is_compatible(phy, "bcm54xx")) tsi_eth_data.phy_type = TSI108_PHY_BCM54XX; of_node_put(phy); ret = platform_device_add_data(tsi_eth_dev, &tsi_eth_data, sizeof(hw_info)); if (ret) goto unreg; } return 0; unreg: platform_device_unregister(tsi_eth_dev); err: return ret; }
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; const unsigned int *prop; unsigned int devflags = 0; enum of_gpio_flags gpio_flags; drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; ret = of_address_to_resource(dp, 0, &memory); if (ret) return -ENXIO; res_len = resource_size(&memory); res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); if (!res) return -EBUSY; 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 */ prop = of_get_property(dp, "bus-width", NULL); if (prop && *prop == 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); kfree(drvdata); return ret; }