struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel) { struct kcs_bmc *kcs_bmc; kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, GFP_KERNEL); if (!kcs_bmc) return NULL; spin_lock_init(&kcs_bmc->lock); kcs_bmc->channel = channel; mutex_init(&kcs_bmc->mutex); init_waitqueue_head(&kcs_bmc->queue); kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR; kcs_bmc->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s%u", DEVICE_NAME, channel); if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer || !kcs_bmc->miscdev.name) return NULL; kcs_bmc->miscdev.fops = &kcs_bmc_fops; return kcs_bmc; }
int mmc_gpio_alloc(struct mmc_host *host) { struct mmc_gpio *ctx = devm_kzalloc(host->parent, sizeof(*ctx), GFP_KERNEL); if (ctx) { ctx->cd_debounce_delay_ms = 200; ctx->cd_label = devm_kasprintf(host->parent, GFP_KERNEL, "%s cd", dev_name(host->parent)); if (!ctx->cd_label) return -ENOMEM; ctx->ro_label = devm_kasprintf(host->parent, GFP_KERNEL, "%s ro", dev_name(host->parent)); if (!ctx->ro_label) return -ENOMEM; host->slot.handler_priv = ctx; host->slot.cd_irq = -EINVAL; } return ctx ? 0 : -ENOMEM; }
static int u2fzero_init_hwrng(struct u2fzero_device *dev, unsigned int minor) { dev->rng_name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, "%s-rng%u", DRIVER_SHORT, minor); if (dev->rng_name == NULL) return -ENOMEM; dev->hwrng.name = dev->rng_name; dev->hwrng.read = u2fzero_rng_read; dev->hwrng.quality = 1; return devm_hwrng_register(&dev->hdev->dev, &dev->hwrng); }
static int bq27x00_battery_probe(struct i2c_client *client, const struct i2c_device_id *id) { char *name; struct bq27x00_device_info *di; int num; int retval = 0; /* Get new ID for the new battery device */ mutex_lock(&battery_mutex); num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL); mutex_unlock(&battery_mutex); if (num < 0) return num; name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num); if (!name) { dev_err(&client->dev, "failed to allocate device name\n"); retval = -ENOMEM; goto batt_failed; } di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); if (!di) { dev_err(&client->dev, "failed to allocate device info data\n"); retval = -ENOMEM; goto batt_failed; } di->id = num; di->dev = &client->dev; di->chip = id->driver_data; di->bus.read = &bq27x00_read_i2c; retval = bq27x00_powersupply_init(di, name); if (retval) goto batt_failed; i2c_set_clientdata(client, di); return 0; batt_failed: mutex_lock(&battery_mutex); idr_remove(&battery_id, num); mutex_unlock(&battery_mutex); return retval; }
static int u2fzero_init_led(struct u2fzero_device *dev, unsigned int minor) { dev->led_name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, "%s%u", DRIVER_SHORT, minor); if (dev->led_name == NULL) return -ENOMEM; dev->ldev.name = dev->led_name; dev->ldev.max_brightness = LED_ON; dev->ldev.flags = LED_HW_PLUGGABLE; dev->ldev.brightness_set_blocking = u2fzero_brightness_set; return devm_led_classdev_register(&dev->hdev->dev, &dev->ldev); }
/** * powernv_flash_set_driver_info - Fill the mtd_info structure and docg3 * structure @pdev: The platform device * @mtd: The structure to fill */ static int powernv_flash_set_driver_info(struct device *dev, struct mtd_info *mtd) { u64 size; u32 erase_size; int rc; rc = of_property_read_u32(dev->of_node, "ibm,flash-block-size", &erase_size); if (rc) { dev_err(dev, "couldn't get resource block size information\n"); return rc; } rc = of_property_read_u64(dev->of_node, "reg", &size); if (rc) { dev_err(dev, "couldn't get resource size information\n"); return rc; } /* * Going to have to check what details I need to set and how to * get them */ mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node); mtd->type = MTD_NORFLASH; mtd->flags = MTD_WRITEABLE; mtd->size = size; mtd->erasesize = erase_size; mtd->writebufsize = mtd->writesize = 1; mtd->owner = THIS_MODULE; mtd->_erase = powernv_flash_erase; mtd->_read = powernv_flash_read; mtd->_write = powernv_flash_write; mtd->dev.parent = dev; mtd_set_of_node(mtd, dev->of_node); return 0; }
static struct regmap *meson_map_resource(struct meson_pinctrl *pc, struct device_node *node, char *name) { struct resource res; void __iomem *base; int i; i = of_property_match_string(node, "reg-names", name); if (of_address_to_resource(node, i, &res)) return ERR_PTR(-ENOENT); base = devm_ioremap_resource(pc->dev, &res); if (IS_ERR(base)) return ERR_CAST(base); meson_regmap_config.max_register = resource_size(&res) - 4; meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL, "%s-%s", node->name, name); if (!meson_regmap_config.name) return ERR_PTR(-ENOMEM); return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config); }
int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, struct regmap *regmap, int (*tsc200x_cmd)(struct device *dev, u8 cmd)) { const struct tsc2005_platform_data *pdata = dev_get_platdata(dev); struct device_node *np = dev->of_node; struct tsc200x *ts; struct input_dev *input_dev; unsigned int max_x = MAX_12BIT; unsigned int max_y = MAX_12BIT; unsigned int max_p = MAX_12BIT; unsigned int fudge_x = TSC200X_DEF_X_FUZZ; unsigned int fudge_y = TSC200X_DEF_Y_FUZZ; unsigned int fudge_p = TSC200X_DEF_P_FUZZ; unsigned int x_plate_ohm = TSC200X_DEF_RESISTOR; unsigned int esd_timeout; int error; if (!np && !pdata) { dev_err(dev, "no platform data\n"); return -ENODEV; } if (irq <= 0) { dev_err(dev, "no irq\n"); return -ENODEV; } if (IS_ERR(regmap)) return PTR_ERR(regmap); if (!tsc200x_cmd) { dev_err(dev, "no cmd function\n"); return -ENODEV; } if (pdata) { fudge_x = pdata->ts_x_fudge; fudge_y = pdata->ts_y_fudge; fudge_p = pdata->ts_pressure_fudge; max_x = pdata->ts_x_max; max_y = pdata->ts_y_max; max_p = pdata->ts_pressure_max; x_plate_ohm = pdata->ts_x_plate_ohm; esd_timeout = pdata->esd_timeout_ms; } else { x_plate_ohm = TSC200X_DEF_RESISTOR; of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm); esd_timeout = 0; of_property_read_u32(np, "ti,esd-recovery-timeout-ms", &esd_timeout); } ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; input_dev = devm_input_allocate_device(dev); if (!input_dev) return -ENOMEM; ts->irq = irq; ts->dev = dev; ts->idev = input_dev; ts->regmap = regmap; ts->tsc200x_cmd = tsc200x_cmd; ts->x_plate_ohm = x_plate_ohm; ts->esd_timeout = esd_timeout; ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ts->reset_gpio)) { error = PTR_ERR(ts->reset_gpio); dev_err(dev, "error acquiring reset gpio: %d\n", error); return error; } ts->vio = devm_regulator_get_optional(dev, "vio"); if (IS_ERR(ts->vio)) { error = PTR_ERR(ts->vio); dev_err(dev, "vio regulator missing (%d)", error); return error; } if (!ts->reset_gpio && pdata) ts->set_reset = pdata->set_reset; mutex_init(&ts->mutex); spin_lock_init(&ts->lock); setup_timer(&ts->penup_timer, tsc200x_penup_timer, (unsigned long)ts); INIT_DELAYED_WORK(&ts->esd_work, tsc200x_esd_work); snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts", dev_name(dev)); if (tsc_id->product == 2004) { input_dev->name = "TSC200X touchscreen"; } else { input_dev->name = devm_kasprintf(dev, GFP_KERNEL, "TSC%04d touchscreen", tsc_id->product); if (!input_dev->name) return -ENOMEM; } input_dev->phys = ts->phys; input_dev->id = *tsc_id; input_dev->dev.parent = dev; input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0); input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); if (np) touchscreen_parse_properties(input_dev, false, NULL); input_dev->open = tsc200x_open; input_dev->close = tsc200x_close; input_set_drvdata(input_dev, ts); /* Ensure the touchscreen is off */ tsc200x_stop_scan(ts); error = devm_request_threaded_irq(dev, irq, NULL, tsc200x_irq_thread, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "tsc200x", ts); if (error) { dev_err(dev, "Failed to request irq, err: %d\n", error); return error; } /* enable regulator for DT */ if (ts->vio) { error = regulator_enable(ts->vio); if (error) return error; } dev_set_drvdata(dev, ts); error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group); if (error) { dev_err(dev, "Failed to create sysfs attributes, err: %d\n", error); goto disable_regulator; } error = input_register_device(ts->idev); if (error) { dev_err(dev, "Failed to register input device, err: %d\n", error); goto err_remove_sysfs; } irq_set_irq_wake(irq, 1); return 0; err_remove_sysfs: sysfs_remove_group(&dev->kobj, &tsc200x_attr_group); disable_regulator: if (ts->vio) regulator_disable(ts->vio); return error; }
static int bq27xxx_battery_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bq27xxx_device_info *di; int ret; char *name; int num; /* Get new ID for the new battery device */ mutex_lock(&battery_mutex); num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL); mutex_unlock(&battery_mutex); if (num < 0) return num; name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num); if (!name) goto err_mem; di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); if (!di) goto err_mem; di->id = num; di->dev = &client->dev; di->chip = id->driver_data; di->name = name; di->bus.read = bq27xxx_battery_i2c_read; ret = bq27xxx_battery_setup(di); if (ret) goto err_failed; /* Schedule a polling after about 1 min */ schedule_delayed_work(&di->work, 60 * HZ); i2c_set_clientdata(client, di); if (client->irq) { ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, bq27xxx_battery_irq_handler_thread, IRQF_ONESHOT, di->name, di); if (ret) { dev_err(&client->dev, "Unable to register IRQ %d error %d\n", client->irq, ret); return ret; } } return 0; err_mem: ret = -ENOMEM; err_failed: mutex_lock(&battery_mutex); idr_remove(&battery_id, num); mutex_unlock(&battery_mutex); return ret; }
static int bq24735_charger_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret; struct bq24735 *charger; struct power_supply_desc *supply_desc; struct power_supply_config psy_cfg = {}; char *name; charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL); if (!charger) return -ENOMEM; charger->pdata = client->dev.platform_data; if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node) charger->pdata = bq24735_parse_dt_data(client); if (!charger->pdata) { dev_err(&client->dev, "no platform data provided\n"); return -EINVAL; } name = (char *)charger->pdata->name; if (!name) { name = devm_kasprintf(&client->dev, GFP_KERNEL, "bq24735@%s", dev_name(&client->dev)); if (!name) { dev_err(&client->dev, "Failed to alloc device name\n"); return -ENOMEM; } } charger->client = client; supply_desc = &charger->charger_desc; supply_desc->name = name; supply_desc->type = POWER_SUPPLY_TYPE_MAINS; supply_desc->properties = bq24735_charger_properties; supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties); supply_desc->get_property = bq24735_charger_get_property; psy_cfg.supplied_to = charger->pdata->supplied_to; psy_cfg.num_supplicants = charger->pdata->num_supplicants; psy_cfg.of_node = client->dev.of_node; psy_cfg.drv_data = charger; i2c_set_clientdata(client, charger); ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID); if (ret < 0) { dev_err(&client->dev, "Failed to read manufacturer id : %d\n", ret); return ret; } else if (ret != 0x0040) { dev_err(&client->dev, "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret); return -ENODEV; } ret = bq24735_read_word(client, BQ24735_DEVICE_ID); if (ret < 0) { dev_err(&client->dev, "Failed to read device id : %d\n", ret); return ret; } else if (ret != 0x000B) { dev_err(&client->dev, "device id mismatch. 0x000b != 0x%04x\n", ret); return -ENODEV; } if (gpio_is_valid(charger->pdata->status_gpio)) { ret = devm_gpio_request(&client->dev, charger->pdata->status_gpio, name); if (ret) { dev_err(&client->dev, "Failed GPIO request for GPIO %d: %d\n", charger->pdata->status_gpio, ret); } charger->pdata->status_gpio_valid = !ret; } ret = bq24735_config_charger(charger); if (ret < 0) { dev_err(&client->dev, "failed in configuring charger"); return ret; } /* check for AC adapter presence */ if (bq24735_charger_is_present(charger)) { ret = bq24735_enable_charging(charger); if (ret < 0) { dev_err(&client->dev, "Failed to enable charging\n"); return ret; } } charger->charger = devm_power_supply_register(&client->dev, supply_desc, &psy_cfg); if (IS_ERR(charger->charger)) { ret = PTR_ERR(charger->charger); dev_err(&client->dev, "Failed to register power supply: %d\n", ret); return ret; } if (client->irq) { ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, bq24735_charger_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, supply_desc->name, charger->charger); if (ret) { dev_err(&client->dev, "Unable to register IRQ %d err %d\n", client->irq, ret); return ret; } } return 0; }
int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id, struct regmap *regmap, int (*tsc200x_cmd)(struct device *dev, u8 cmd)) { struct tsc200x *ts; struct input_dev *input_dev; u32 x_plate_ohm; u32 esd_timeout; int error; if (irq <= 0) { dev_err(dev, "no irq\n"); return -ENODEV; } if (IS_ERR(regmap)) return PTR_ERR(regmap); if (!tsc200x_cmd) { dev_err(dev, "no cmd function\n"); return -ENODEV; } ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; input_dev = devm_input_allocate_device(dev); if (!input_dev) return -ENOMEM; ts->irq = irq; ts->dev = dev; ts->idev = input_dev; ts->regmap = regmap; ts->tsc200x_cmd = tsc200x_cmd; error = device_property_read_u32(dev, "ti,x-plate-ohms", &x_plate_ohm); ts->x_plate_ohm = error ? TSC200X_DEF_RESISTOR : x_plate_ohm; error = device_property_read_u32(dev, "ti,esd-recovery-timeout-ms", &esd_timeout); ts->esd_timeout = error ? 0 : esd_timeout; ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ts->reset_gpio)) { error = PTR_ERR(ts->reset_gpio); dev_err(dev, "error acquiring reset gpio: %d\n", error); return error; } ts->vio = devm_regulator_get(dev, "vio"); if (IS_ERR(ts->vio)) { error = PTR_ERR(ts->vio); dev_err(dev, "error acquiring vio regulator: %d", error); return error; } mutex_init(&ts->mutex); spin_lock_init(&ts->lock); setup_timer(&ts->penup_timer, tsc200x_penup_timer, (unsigned long)ts); INIT_DELAYED_WORK(&ts->esd_work, tsc200x_esd_work); snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts", dev_name(dev)); if (tsc_id->product == 2004) { input_dev->name = "TSC200X touchscreen"; } else { input_dev->name = devm_kasprintf(dev, GFP_KERNEL, "TSC%04d touchscreen", tsc_id->product); if (!input_dev->name) return -ENOMEM; } input_dev->phys = ts->phys; input_dev->id = *tsc_id; input_dev->open = tsc200x_open; input_dev->close = tsc200x_close; input_set_drvdata(input_dev, ts); __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); input_set_capability(input_dev, EV_KEY, BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, TSC200X_DEF_X_FUZZ, 0); input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, TSC200X_DEF_Y_FUZZ, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, TSC200X_DEF_P_FUZZ, 0); touchscreen_parse_properties(input_dev, false, NULL); /* Ensure the touchscreen is off */ tsc200x_stop_scan(ts); error = devm_request_threaded_irq(dev, irq, NULL, tsc200x_irq_thread, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "tsc200x", ts); if (error) { dev_err(dev, "Failed to request irq, err: %d\n", error); return error; } error = regulator_enable(ts->vio); if (error) return error; dev_set_drvdata(dev, ts); error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group); if (error) { dev_err(dev, "Failed to create sysfs attributes, err: %d\n", error); goto disable_regulator; } error = input_register_device(ts->idev); if (error) { dev_err(dev, "Failed to register input device, err: %d\n", error); goto err_remove_sysfs; } irq_set_irq_wake(irq, 1); return 0; err_remove_sysfs: sysfs_remove_group(&dev->kobj, &tsc200x_attr_group); disable_regulator: regulator_disable(ts->vio); return error; }
static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac) { struct clk_init_data init; int i, ret; struct device *dev = &dwmac->pdev->dev; char clk_name[32]; const char *clk_div_parents[1]; const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; /* get the mux parents from DT */ for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) { char name[16]; snprintf(name, sizeof(name), "clkin%d", i); dwmac->m250_mux_parent[i] = devm_clk_get(dev, name); if (IS_ERR(dwmac->m250_mux_parent[i])) { ret = PTR_ERR(dwmac->m250_mux_parent[i]); if (ret != -EPROBE_DEFER) dev_err(dev, "Missing clock %s\n", name); return ret; } mux_parent_names[i] = __clk_get_name(dwmac->m250_mux_parent[i]); } /* create the m250_mux */ snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev)); init.name = clk_name; init.ops = &clk_mux_ops; init.flags = CLK_SET_RATE_PARENT; init.parent_names = mux_parent_names; init.num_parents = MUX_CLK_NUM_PARENTS; dwmac->m250_mux.reg = dwmac->regs + PRG_ETH0; dwmac->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT; dwmac->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK; dwmac->m250_mux.flags = 0; dwmac->m250_mux.table = NULL; dwmac->m250_mux.hw.init = &init; dwmac->m250_mux_clk = devm_clk_register(dev, &dwmac->m250_mux.hw); if (WARN_ON(IS_ERR(dwmac->m250_mux_clk))) return PTR_ERR(dwmac->m250_mux_clk); /* create the m250_div */ snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev)); init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL); init.ops = &clk_divider_ops; init.flags = CLK_SET_RATE_PARENT; clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk); init.parent_names = clk_div_parents; init.num_parents = ARRAY_SIZE(clk_div_parents); dwmac->m250_div.reg = dwmac->regs + PRG_ETH0; dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT; dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH; dwmac->m250_div.hw.init = &init; dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO | CLK_DIVIDER_ROUND_CLOSEST; dwmac->m250_div_clk = devm_clk_register(dev, &dwmac->m250_div.hw); if (WARN_ON(IS_ERR(dwmac->m250_div_clk))) return PTR_ERR(dwmac->m250_div_clk); /* create the fixed_div2 */ snprintf(clk_name, sizeof(clk_name), "%s#fixed_div2", dev_name(dev)); init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL); init.ops = &clk_fixed_factor_ops; init.flags = CLK_SET_RATE_PARENT; clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk); init.parent_names = clk_div_parents; init.num_parents = ARRAY_SIZE(clk_div_parents); dwmac->fixed_div2.mult = 1; dwmac->fixed_div2.div = 2; dwmac->fixed_div2.hw.init = &init; dwmac->fixed_div2_clk = devm_clk_register(dev, &dwmac->fixed_div2.hw); if (WARN_ON(IS_ERR(dwmac->fixed_div2_clk))) return PTR_ERR(dwmac->fixed_div2_clk); /* create the rgmii_tx_en */ init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#rgmii_tx_en", dev_name(dev)); init.ops = &clk_gate_ops; init.flags = CLK_SET_RATE_PARENT; clk_div_parents[0] = __clk_get_name(dwmac->fixed_div2_clk); init.parent_names = clk_div_parents; init.num_parents = ARRAY_SIZE(clk_div_parents); dwmac->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0; dwmac->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN; dwmac->rgmii_tx_en.hw.init = &init; dwmac->rgmii_tx_en_clk = devm_clk_register(dev, &dwmac->rgmii_tx_en.hw); if (WARN_ON(IS_ERR(dwmac->rgmii_tx_en_clk))) return PTR_ERR(dwmac->rgmii_tx_en_clk); return 0; }
static int tb10x_gpio_probe(struct platform_device *pdev) { struct tb10x_gpio *tb10x_gpio; struct resource *mem; struct device_node *dn = pdev->dev.of_node; int ret = -EBUSY; u32 ngpio; if (!dn) return -EINVAL; if (of_property_read_u32(dn, "abilis,ngpio", &ngpio)) return -EINVAL; tb10x_gpio = devm_kzalloc(&pdev->dev, sizeof(*tb10x_gpio), GFP_KERNEL); if (tb10x_gpio == NULL) return -ENOMEM; spin_lock_init(&tb10x_gpio->spinlock); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); tb10x_gpio->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(tb10x_gpio->base)) return PTR_ERR(tb10x_gpio->base); tb10x_gpio->gc.label = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOF", pdev->dev.of_node); if (!tb10x_gpio->gc.label) return -ENOMEM; tb10x_gpio->gc.parent = &pdev->dev; tb10x_gpio->gc.owner = THIS_MODULE; tb10x_gpio->gc.direction_input = tb10x_gpio_direction_in; tb10x_gpio->gc.get = tb10x_gpio_get; tb10x_gpio->gc.direction_output = tb10x_gpio_direction_out; tb10x_gpio->gc.set = tb10x_gpio_set; tb10x_gpio->gc.request = gpiochip_generic_request; tb10x_gpio->gc.free = gpiochip_generic_free; tb10x_gpio->gc.base = -1; tb10x_gpio->gc.ngpio = ngpio; tb10x_gpio->gc.can_sleep = false; ret = devm_gpiochip_add_data(&pdev->dev, &tb10x_gpio->gc, tb10x_gpio); if (ret < 0) { dev_err(&pdev->dev, "Could not add gpiochip.\n"); return ret; } platform_set_drvdata(pdev, tb10x_gpio); if (of_find_property(dn, "interrupt-controller", NULL)) { struct irq_chip_generic *gc; ret = platform_get_irq(pdev, 0); if (ret < 0) { dev_err(&pdev->dev, "No interrupt specified.\n"); return ret; } tb10x_gpio->gc.to_irq = tb10x_gpio_to_irq; tb10x_gpio->irq = ret; ret = devm_request_irq(&pdev->dev, ret, tb10x_gpio_irq_cascade, IRQF_TRIGGER_NONE | IRQF_SHARED, dev_name(&pdev->dev), tb10x_gpio); if (ret != 0) return ret; tb10x_gpio->domain = irq_domain_add_linear(dn, tb10x_gpio->gc.ngpio, &irq_generic_chip_ops, NULL); if (!tb10x_gpio->domain) { return -ENOMEM; } ret = irq_alloc_domain_generic_chips(tb10x_gpio->domain, tb10x_gpio->gc.ngpio, 1, tb10x_gpio->gc.label, handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, IRQ_GC_INIT_MASK_CACHE); if (ret) return ret; gc = tb10x_gpio->domain->gc->gc[0]; gc->reg_base = tb10x_gpio->base; gc->chip_types[0].type = IRQ_TYPE_EDGE_BOTH; gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[0].chip.irq_set_type = tb10x_gpio_irq_set_type; gc->chip_types[0].regs.ack = OFFSET_TO_REG_CHANGE; gc->chip_types[0].regs.mask = OFFSET_TO_REG_INT_EN; } return 0; }
static int rcar_gen3_thermal_probe(struct platform_device *pdev) { struct rcar_gen3_thermal_priv *priv; struct device *dev = &pdev->dev; struct resource *res; struct thermal_zone_device *zone; int ret, irq, i; char *irqname; /* default values if FUSEs are missing */ /* TODO: Read values from hardware on supported platforms */ int ptat[3] = { 2631, 1509, 435 }; int thcode[TSC_MAX_NUM][3] = { { 3397, 2800, 2221 }, { 3393, 2795, 2216 }, { 3389, 2805, 2237 }, }; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->thermal_init = rcar_gen3_thermal_init; if (soc_device_match(r8a7795es1)) priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1; spin_lock_init(&priv->lock); platform_set_drvdata(pdev, priv); /* * Request 2 (of the 3 possible) IRQs, the driver only needs to * to trigger on the low and high trip points of the current * temp window at this point. */ for (i = 0; i < 2; i++) { irq = platform_get_irq(pdev, i); if (irq < 0) return irq; irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d", dev_name(dev), i); if (!irqname) return -ENOMEM; ret = devm_request_threaded_irq(dev, irq, rcar_gen3_thermal_irq, rcar_gen3_thermal_irq_thread, IRQF_SHARED, irqname, priv); if (ret) return ret; } pm_runtime_enable(dev); pm_runtime_get_sync(dev); for (i = 0; i < TSC_MAX_NUM; i++) { struct rcar_gen3_thermal_tsc *tsc; res = platform_get_resource(pdev, IORESOURCE_MEM, i); if (!res) break; tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL); if (!tsc) { ret = -ENOMEM; goto error_unregister; } tsc->base = devm_ioremap_resource(dev, res); if (IS_ERR(tsc->base)) { ret = PTR_ERR(tsc->base); goto error_unregister; } priv->tscs[i] = tsc; priv->thermal_init(tsc); rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); zone = devm_thermal_zone_of_sensor_register(dev, i, tsc, &rcar_gen3_tz_of_ops); if (IS_ERR(zone)) { dev_err(dev, "Can't register thermal zone\n"); ret = PTR_ERR(zone); goto error_unregister; } tsc->zone = zone; ret = of_thermal_get_ntrips(tsc->zone); if (ret < 0) goto error_unregister; dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret); } priv->num_tscs = i; if (!priv->num_tscs) { ret = -ENODEV; goto error_unregister; } rcar_thermal_irq_set(priv, true); return 0; error_unregister: rcar_gen3_thermal_remove(pdev); return ret; }
static int iio_hwmon_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct iio_hwmon_state *st; struct sensor_device_attribute *a; int ret, i; int in_i = 1, temp_i = 1, curr_i = 1, humidity_i = 1; enum iio_chan_type type; struct iio_channel *channels; const char *name = "iio_hwmon"; struct device *hwmon_dev; char *sname; if (dev->of_node && dev->of_node->name) name = dev->of_node->name; channels = devm_iio_channel_get_all(dev); if (IS_ERR(channels)) { if (PTR_ERR(channels) == -ENODEV) return -EPROBE_DEFER; return PTR_ERR(channels); } st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); if (st == NULL) return -ENOMEM; st->channels = channels; /* count how many attributes we have */ while (st->channels[st->num_channels].indio_dev) st->num_channels++; st->attrs = devm_kcalloc(dev, st->num_channels + 1, sizeof(*st->attrs), GFP_KERNEL); if (st->attrs == NULL) return -ENOMEM; for (i = 0; i < st->num_channels; i++) { a = devm_kzalloc(dev, sizeof(*a), GFP_KERNEL); if (a == NULL) return -ENOMEM; sysfs_attr_init(&a->dev_attr.attr); ret = iio_get_channel_type(&st->channels[i], &type); if (ret < 0) return ret; switch (type) { case IIO_VOLTAGE: a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "in%d_input", in_i++); break; case IIO_TEMP: a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "temp%d_input", temp_i++); break; case IIO_CURRENT: a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "curr%d_input", curr_i++); break; case IIO_HUMIDITYRELATIVE: a->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "humidity%d_input", humidity_i++); break; default: return -EINVAL; } if (a->dev_attr.attr.name == NULL) return -ENOMEM; a->dev_attr.show = iio_hwmon_read_val; a->dev_attr.attr.mode = S_IRUGO; a->index = i; st->attrs[i] = &a->dev_attr.attr; } st->attr_group.attrs = st->attrs; st->groups[0] = &st->attr_group; sname = devm_kstrdup(dev, name, GFP_KERNEL); if (!sname) return -ENOMEM; strreplace(sname, '-', '_'); hwmon_dev = devm_hwmon_device_register_with_groups(dev, sname, st, st->groups); return PTR_ERR_OR_ZERO(hwmon_dev); }
static int omap_hdmi_audio_probe(struct platform_device *pdev) { struct omap_hdmi_audio_pdata *ha = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct hdmi_audio_data *ad; struct snd_soc_dai_driver *dai_drv; struct snd_soc_card *card; int ret; if (!ha) { dev_err(dev, "No platform data\n"); return -EINVAL; } ad = devm_kzalloc(dev, sizeof(*ad), GFP_KERNEL); if (!ad) return -ENOMEM; ad->dssdev = ha->dev; ad->ops = ha->ops; ad->dma_data.addr = ha->audio_dma_addr; ad->dma_data.filter_data = "audio_tx"; ad->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; mutex_init(&ad->current_stream_lock); switch (ha->dss_version) { case OMAPDSS_VER_OMAP4430_ES1: case OMAPDSS_VER_OMAP4430_ES2: case OMAPDSS_VER_OMAP4: dai_drv = &omap4_hdmi_dai; break; case OMAPDSS_VER_OMAP5: dai_drv = &omap5_hdmi_dai; break; default: return -EINVAL; } ret = snd_soc_register_component(ad->dssdev, &omap_hdmi_component, dai_drv, 1); if (ret) return ret; ret = omap_pcm_platform_register(ad->dssdev); if (ret) return ret; card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) return -ENOMEM; card->name = devm_kasprintf(dev, GFP_KERNEL, "HDMI %s", dev_name(ad->dssdev)); card->owner = THIS_MODULE; card->dai_link = devm_kzalloc(dev, sizeof(*(card->dai_link)), GFP_KERNEL); card->dai_link->name = card->name; card->dai_link->stream_name = card->name; card->dai_link->cpu_dai_name = dev_name(ad->dssdev); card->dai_link->platform_name = dev_name(ad->dssdev); card->dai_link->codec_name = "snd-soc-dummy"; card->dai_link->codec_dai_name = "snd-soc-dummy-dai"; card->num_links = 1; card->dev = dev; ret = snd_soc_register_card(card); if (ret) { dev_err(dev, "snd_soc_register_card failed (%d)\n", ret); snd_soc_unregister_component(ad->dssdev); return ret; } ad->card = card; snd_soc_card_set_drvdata(card, ad); dev_set_drvdata(dev, ad); 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 etm_probe(struct amba_device *adev, const struct amba_id *id) { int ret; void __iomem *base; struct device *dev = &adev->dev; struct coresight_platform_data *pdata = NULL; struct etm_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; drvdata->use_cp14 = fwnode_property_read_bool(dev->fwnode, "arm,cp14"); dev_set_drvdata(dev, drvdata); /* Validity for the resource is already checked by the AMBA core */ base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); drvdata->base = base; spin_lock_init(&drvdata->spinlock); drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret = clk_prepare_enable(drvdata->atclk); if (ret) return ret; } drvdata->cpu = coresight_get_cpu(dev); desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu); if (!desc.name) return -ENOMEM; cpus_read_lock(); etmdrvdata[drvdata->cpu] = drvdata; if (smp_call_function_single(drvdata->cpu, etm_init_arch_data, drvdata, 1)) dev_err(dev, "ETM arch init failed\n"); if (!etm_count++) { cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING, "arm/coresight:starting", etm_starting_cpu, etm_dying_cpu); ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN, "arm/coresight:online", etm_online_cpu, NULL); if (ret < 0) goto err_arch_supported; hp_online = ret; } cpus_read_unlock(); if (etm_arch_supported(drvdata->arch) == false) { ret = -EINVAL; goto err_arch_supported; } etm_init_trace_id(drvdata); etm_set_default(&drvdata->config); pdata = coresight_get_platform_data(dev); if (IS_ERR(pdata)) { ret = PTR_ERR(pdata); goto err_arch_supported; } adev->dev.platform_data = pdata; desc.type = CORESIGHT_DEV_TYPE_SOURCE; desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc.ops = &etm_cs_ops; desc.pdata = pdata; desc.dev = dev; desc.groups = coresight_etm_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); goto err_arch_supported; } ret = etm_perf_symlink(drvdata->csdev, true); if (ret) { coresight_unregister(drvdata->csdev); goto err_arch_supported; } pm_runtime_put(&adev->dev); dev_info(&drvdata->csdev->dev, "%s initialized\n", (char *)coresight_get_uci_data(id)); if (boot_enable) { coresight_enable(drvdata->csdev); drvdata->boot_enable = true; } return 0; err_arch_supported: if (--etm_count == 0) { cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING); if (hp_online) cpuhp_remove_state_nocalls(hp_online); } return ret; }