static int u2fzero_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct u2fzero_device *dev; unsigned int minor; int ret; if (!hid_is_using_ll_driver(hdev, &usb_hid_driver)) return -EINVAL; dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); if (dev == NULL) return -ENOMEM; dev->buf_out = devm_kmalloc(&hdev->dev, sizeof(struct u2f_hid_report), GFP_KERNEL); if (dev->buf_out == NULL) return -ENOMEM; dev->buf_in = devm_kmalloc(&hdev->dev, sizeof(struct u2f_hid_msg), GFP_KERNEL); if (dev->buf_in == NULL) return -ENOMEM; ret = hid_parse(hdev); if (ret) return ret; dev->hdev = hdev; hid_set_drvdata(hdev, dev); mutex_init(&dev->lock); ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); if (ret) return ret; u2fzero_fill_in_urb(dev); dev->present = true; minor = ((struct hidraw *) hdev->hidraw)->minor; ret = u2fzero_init_led(dev, minor); if (ret) { hid_hw_stop(hdev); return ret; } hid_info(hdev, "U2F Zero LED initialised\n"); ret = u2fzero_init_hwrng(dev, minor); if (ret) { hid_hw_stop(hdev); return ret; } hid_info(hdev, "U2F Zero RNG initialised\n"); return 0; }
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; }
struct hisi_clock_data *hisi_clk_alloc(struct platform_device *pdev, int nr_clks) { struct hisi_clock_data *clk_data; struct resource *res; struct clk **clk_table; clk_data = devm_kmalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); if (!clk_data) return NULL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return NULL; clk_data->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!clk_data->base) return NULL; clk_table = devm_kmalloc_array(&pdev->dev, nr_clks, sizeof(*clk_table), GFP_KERNEL); if (!clk_table) return NULL; clk_data->clk_data.clks = clk_table; clk_data->clk_data.clk_num = nr_clks; return clk_data; }
static int hi3798cv200_crg_probe(struct platform_device *pdev) { struct hisi_crg_dev *crg; crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL); if (!crg) return -ENOMEM; crg->funcs = of_device_get_match_data(&pdev->dev); if (!crg->funcs) return -ENOENT; crg->rstc = hisi_reset_init(pdev); if (!crg->rstc) return -ENOMEM; crg->clk_data = crg->funcs->register_clks(pdev); if (IS_ERR(crg->clk_data)) { hisi_reset_exit(crg->rstc); return PTR_ERR(crg->clk_data); } platform_set_drvdata(pdev, crg); return 0; }
static int scpi_clk_add(struct device *dev, struct device_node *np, const struct of_device_id *match) { struct clk **clks; int idx, count; struct scpi_clk_data *clk_data; count = of_property_count_strings(np, "clock-output-names"); if (count < 0) { dev_err(dev, "%s: invalid clock output count\n", np->name); return -EINVAL; } clk_data = devm_kmalloc(dev, sizeof(*clk_data), GFP_KERNEL); if (!clk_data) return -ENOMEM; clk_data->clk_num = count; clk_data->clk = devm_kcalloc(dev, count, sizeof(*clk_data->clk), GFP_KERNEL); if (!clk_data->clk) return -ENOMEM; clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL); if (!clks) return -ENOMEM; for (idx = 0; idx < count; idx++) { struct scpi_clk *sclk; const char *name; u32 val; sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL); if (!sclk) return -ENOMEM; if (of_property_read_string_index(np, "clock-output-names", idx, &name)) { dev_err(dev, "invalid clock name @ %s\n", np->name); return -EINVAL; } if (of_property_read_u32_index(np, "clock-indices", idx, &val)) { dev_err(dev, "invalid clock index @ %s\n", np->name); return -EINVAL; } sclk->id = val; clks[idx] = scpi_clk_ops_init(dev, match, sclk, name); if (IS_ERR_OR_NULL(clks[idx])) dev_err(dev, "failed to register clock '%s'\n", name); else dev_dbg(dev, "Registered clock '%s'\n", name); clk_data->clk[idx] = sclk; } return of_clk_add_provider(np, scpi_of_clk_src_get, clk_data); }
static int create_sysfs_entry_channel(struct hidma_mgmt_dev *mdev, char *name, int mode, int index, struct kobject *parent) { struct hidma_chan_attr *chattr; char *name_copy; chattr = devm_kmalloc(&mdev->pdev->dev, sizeof(*chattr), GFP_KERNEL); if (!chattr) return -ENOMEM; name_copy = devm_kstrdup(&mdev->pdev->dev, name, GFP_KERNEL); if (!name_copy) return -ENOMEM; chattr->mdev = mdev; chattr->index = index; chattr->attr.attr.name = name_copy; chattr->attr.attr.mode = mode; chattr->attr.show = show_values_channel; chattr->attr.store = set_values_channel; sysfs_attr_init(&chattr->attr.attr); return sysfs_create_file(parent, &chattr->attr.attr); }
int mt7601u_register_device(struct mt7601u_dev *dev) { struct ieee80211_hw *hw = dev->hw; struct wiphy *wiphy = hw->wiphy; int ret; /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to * entry no. 1 like it does in the vendor driver. */ dev->wcid_mask[0] |= 1; /* init fake wcid for monitor interfaces */ dev->mon_wcid = devm_kmalloc(dev->dev, sizeof(*dev->mon_wcid), GFP_KERNEL); if (!dev->mon_wcid) return -ENOMEM; dev->mon_wcid->idx = 0xff; dev->mon_wcid->hw_key_idx = -1; SET_IEEE80211_DEV(hw, dev->dev); hw->queues = 4; ieee80211_hw_set(hw, SIGNAL_DBM); ieee80211_hw_set(hw, PS_NULLFUNC_STACK); ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); ieee80211_hw_set(hw, AMPDU_AGGREGATION); ieee80211_hw_set(hw, SUPPORTS_RC_TABLE); hw->max_rates = 1; hw->max_report_rates = 7; hw->max_rate_tries = 1; hw->sta_data_size = sizeof(struct mt76_sta); hw->vif_data_size = sizeof(struct mt76_vif); SET_IEEE80211_PERM_ADDR(hw, dev->macaddr); wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); ret = mt76_init_sband_2g(dev); if (ret) return ret; INIT_DELAYED_WORK(&dev->mac_work, mt7601u_mac_work); INIT_DELAYED_WORK(&dev->stat_work, mt7601u_tx_stat); ret = ieee80211_register_hw(hw); if (ret) return ret; mt7601u_init_debugfs(dev); return 0; }
int hidma_mgmt_init_sys(struct hidma_mgmt_dev *mdev) { unsigned int i; int rc; int required; struct kobject *chanops; required = sizeof(*mdev->chroots) * mdev->dma_channels; mdev->chroots = devm_kmalloc(&mdev->pdev->dev, required, GFP_KERNEL); if (!mdev->chroots) return -ENOMEM; chanops = kobject_create_and_add("chanops", &mdev->pdev->dev.kobj); if (!chanops) return -ENOMEM; /* create each channel directory here */ for (i = 0; i < mdev->dma_channels; i++) { char name[20]; snprintf(name, sizeof(name), "chan%d", i); mdev->chroots[i] = kobject_create_and_add(name, chanops); if (!mdev->chroots[i]) return -ENOMEM; } /* populate common parameters */ for (i = 0; i < ARRAY_SIZE(hidma_mgmt_files); i++) { rc = create_sysfs_entry(mdev, hidma_mgmt_files[i].name, hidma_mgmt_files[i].mode); if (rc) return rc; } /* populate parameters that are per channel */ for (i = 0; i < mdev->dma_channels; i++) { rc = create_sysfs_entry_channel(mdev, "priority", (S_IRUGO | S_IWUGO), i, mdev->chroots[i]); if (rc) return rc; rc = create_sysfs_entry_channel(mdev, "weight", (S_IRUGO | S_IWUGO), i, mdev->chroots[i]); if (rc) return rc; } return 0; }
/** * devm_kstrdup - Allocate resource managed space and * copy an existing string into that. * @dev: Device to allocate memory for * @s: the string to duplicate * @gfp: the GFP mask used in the devm_kmalloc() call when * allocating memory * RETURNS: * Pointer to allocated string on success, NULL on failure. */ char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) { size_t size; char *buf; if (!s) return NULL; size = strlen(s) + 1; buf = devm_kmalloc(dev, size, gfp); if (buf) memcpy(buf, s, size); return buf; }
static void fdp_nci_i2c_read_device_properties(struct device *dev, u8 *clock_type, u32 *clock_freq, u8 **fw_vsc_cfg) { int r; u8 len; r = device_property_read_u8(dev, FDP_DP_CLOCK_TYPE_NAME, clock_type); if (r) { dev_dbg(dev, "Using default clock type"); *clock_type = 0; } r = device_property_read_u32(dev, FDP_DP_CLOCK_FREQ_NAME, clock_freq); if (r) { dev_dbg(dev, "Using default clock frequency\n"); *clock_freq = 26000; } if (device_property_present(dev, FDP_DP_FW_VSC_CFG_NAME)) { r = device_property_read_u8(dev, FDP_DP_FW_VSC_CFG_NAME, &len); if (r || len <= 0) goto vsc_read_err; /* Add 1 to the length to inclue the length byte itself */ len++; *fw_vsc_cfg = devm_kmalloc(dev, len * sizeof(**fw_vsc_cfg), GFP_KERNEL); r = device_property_read_u8_array(dev, FDP_DP_FW_VSC_CFG_NAME, *fw_vsc_cfg, len); if (r) { devm_kfree(dev, fw_vsc_cfg); goto vsc_read_err; } } else { vsc_read_err: dev_dbg(dev, "FW vendor specific commands not present\n"); *fw_vsc_cfg = NULL; } dev_dbg(dev, "Clock type: %d, clock frequency: %d, VSC: %s", *clock_type, *clock_freq, *fw_vsc_cfg != NULL ? "yes" : "no"); }
static int rvu_map_cgx_lmac_pf(struct rvu *rvu) { struct npc_pkind *pkind = &rvu->hw->pkind; int cgx_cnt_max = rvu->cgx_cnt_max; int cgx, lmac_cnt, lmac; int pf = PF_CGXMAP_BASE; int size, free_pkind; if (!cgx_cnt_max) return 0; if (cgx_cnt_max > 0xF || MAX_LMAC_PER_CGX > 0xF) return -EINVAL; /* Alloc map table * An additional entry is required since PF id starts from 1 and * hence entry at offset 0 is invalid. */ size = (cgx_cnt_max * MAX_LMAC_PER_CGX + 1) * sizeof(u8); rvu->pf2cgxlmac_map = devm_kmalloc(rvu->dev, size, GFP_KERNEL); if (!rvu->pf2cgxlmac_map) return -ENOMEM; /* Initialize all entries with an invalid cgx and lmac id */ memset(rvu->pf2cgxlmac_map, 0xFF, size); /* Reverse map table */ rvu->cgxlmac2pf_map = devm_kzalloc(rvu->dev, cgx_cnt_max * MAX_LMAC_PER_CGX * sizeof(u16), GFP_KERNEL); if (!rvu->cgxlmac2pf_map) return -ENOMEM; rvu->cgx_mapped_pfs = 0; for (cgx = 0; cgx < cgx_cnt_max; cgx++) { if (!rvu_cgx_pdata(cgx, rvu)) continue; lmac_cnt = cgx_get_lmac_cnt(rvu_cgx_pdata(cgx, rvu)); for (lmac = 0; lmac < lmac_cnt; lmac++, pf++) { rvu->pf2cgxlmac_map[pf] = cgxlmac_id_to_bmap(cgx, lmac); rvu->cgxlmac2pf_map[CGX_OFFSET(cgx) + lmac] = 1 << pf; free_pkind = rvu_alloc_rsrc(&pkind->rsrc); pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16; rvu->cgx_mapped_pfs++; } } return 0; }
static int s5p_ehci_clk_get(struct s5p_ehci_hcd *s5p_ehci, struct device *dev) { const char *clk_id; const char **s5p_ehci_clk_names; struct clk *clk; int size; int i; clk_id = "usbhost"; clk = devm_clk_get(dev, clk_id); if (IS_ERR_OR_NULL(clk)) { dev_info(dev, "IP clock gating is N/A\n"); s5p_ehci->clk = NULL; /* fallback to separate clock control */ s5p_ehci_clk_names = s5p_ehci->drvdata->clk_names; size = s5p_ehci->drvdata->clk_size; s5p_ehci->clocks = (struct clk **) devm_kmalloc(dev, size * sizeof(struct clk *), GFP_KERNEL); if (!s5p_ehci->clocks) return -ENOMEM; for (i = 0; s5p_ehci_clk_names[i] != NULL; i++) { clk_id = s5p_ehci_clk_names[i]; clk = devm_clk_get(dev, clk_id); if (IS_ERR_OR_NULL(clk)) goto err; s5p_ehci->clocks[i] = clk; } s5p_ehci->clocks[i] = NULL; } else { s5p_ehci->clk = clk; } return 0; err: dev_err(dev, "couldn't get %s clock\n", clk_id); return -EINVAL; }
/** * devm_kvasprintf - Allocate resource managed space * for the formatted string. * @dev: Device to allocate memory for * @gfp: the GFP mask used in the devm_kmalloc() call when * allocating memory * @fmt: the formatted string to duplicate * @ap: the list of tokens to be placed in the formatted string * RETURNS: * Pointer to allocated string on success, NULL on failure. */ char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, va_list ap) { unsigned int len; char *p; va_list aq; va_copy(aq, ap); len = vsnprintf(NULL, 0, fmt, aq); va_end(aq); p = devm_kmalloc(dev, len+1, gfp); if (!p) return NULL; vsnprintf(p, len+1, fmt, ap); return p; }
static int tc_cfg_probe(struct platform_device *pdev) { pr_info("%s.\n",__FUNCTION__); tc_cfg_reg = devm_kmalloc(&pdev->dev,sizeof(struct at_case_type), GFP_ATOMIC); if(NULL == tc_cfg_reg){ return -ENOMEM; } tc_cfg_reg->test_name = "tc_cfg_reg"; tc_cfg_reg->test_params = 0; tc_cfg_reg->test_pri = AT_CASE_PRI_HIG; tc_cfg_reg->prepare = tc_cfg_reg_prepare; tc_cfg_reg->begin = tc_cfg_reg_beg; tc_cfg_reg->stop = tc_cfg_reg_stop; //at_core_register_test_case(tc_cfg_reg); return 0; }
static int create_sysfs_entry(struct hidma_mgmt_dev *dev, char *name, int mode) { struct device_attribute *attrs; char *name_copy; attrs = devm_kmalloc(&dev->pdev->dev, sizeof(struct device_attribute), GFP_KERNEL); if (!attrs) return -ENOMEM; name_copy = devm_kstrdup(&dev->pdev->dev, name, GFP_KERNEL); if (!name_copy) return -ENOMEM; attrs->attr.name = name_copy; attrs->attr.mode = mode; attrs->show = show_values; attrs->store = set_values; sysfs_attr_init(&attrs->attr); return device_create_file(&dev->pdev->dev, attrs); }
static int armada_xp_pinctrl_probe(struct platform_device *pdev) { struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info; const struct of_device_id *match = of_match_device(armada_xp_pinctrl_of_match, &pdev->dev); int nregs; if (!match) return -ENODEV; soc->variant = (unsigned) match->data & 0xff; switch (soc->variant) { case V_MV78230: soc->controls = mv78230_mpp_controls; soc->ncontrols = ARRAY_SIZE(mv78230_mpp_controls); soc->modes = armada_xp_mpp_modes; /* We don't necessarily want the full list of the * armada_xp_mpp_modes, but only the first 'n' ones * that are available on this SoC */ soc->nmodes = mv78230_mpp_controls[0].npins; soc->gpioranges = mv78230_mpp_gpio_ranges; soc->ngpioranges = ARRAY_SIZE(mv78230_mpp_gpio_ranges); break; case V_MV78260: soc->controls = mv78260_mpp_controls; soc->ncontrols = ARRAY_SIZE(mv78260_mpp_controls); soc->modes = armada_xp_mpp_modes; /* We don't necessarily want the full list of the * armada_xp_mpp_modes, but only the first 'n' ones * that are available on this SoC */ soc->nmodes = mv78260_mpp_controls[0].npins; soc->gpioranges = mv78260_mpp_gpio_ranges; soc->ngpioranges = ARRAY_SIZE(mv78260_mpp_gpio_ranges); break; case V_MV78460: soc->controls = mv78460_mpp_controls; soc->ncontrols = ARRAY_SIZE(mv78460_mpp_controls); soc->modes = armada_xp_mpp_modes; /* We don't necessarily want the full list of the * armada_xp_mpp_modes, but only the first 'n' ones * that are available on this SoC */ soc->nmodes = mv78460_mpp_controls[0].npins; soc->gpioranges = mv78460_mpp_gpio_ranges; soc->ngpioranges = ARRAY_SIZE(mv78460_mpp_gpio_ranges); break; case V_98DX3236: case V_98DX3336: case V_98DX4251: /* fall-through */ soc->controls = mv98dx3236_mpp_controls; soc->ncontrols = ARRAY_SIZE(mv98dx3236_mpp_controls); soc->modes = mv98dx3236_mpp_modes; soc->nmodes = mv98dx3236_mpp_controls[0].npins; soc->gpioranges = mv98dx3236_mpp_gpio_ranges; soc->ngpioranges = ARRAY_SIZE(mv98dx3236_mpp_gpio_ranges); break; } nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG); mpp_saved_regs = devm_kmalloc(&pdev->dev, nregs * sizeof(u32), GFP_KERNEL); if (!mpp_saved_regs) return -ENOMEM; pdev->dev.platform_data = soc; return mvebu_pinctrl_simple_mmio_probe(pdev); }
static int ipmi_powernv_probe(struct platform_device *pdev) { struct ipmi_smi_powernv *ipmi; struct device *dev; u32 prop; int rc; if (!pdev || !pdev->dev.of_node) return -ENODEV; dev = &pdev->dev; ipmi = devm_kzalloc(dev, sizeof(*ipmi), GFP_KERNEL); if (!ipmi) return -ENOMEM; spin_lock_init(&ipmi->msg_lock); rc = of_property_read_u32(dev->of_node, "ibm,ipmi-interface-id", &prop); if (rc) { dev_warn(dev, "No interface ID property\n"); goto err_free; } ipmi->interface_id = prop; rc = of_property_read_u32(dev->of_node, "interrupts", &prop); if (rc) { dev_warn(dev, "No interrupts property\n"); goto err_free; } ipmi->irq = irq_of_parse_and_map(dev->of_node, 0); if (!ipmi->irq) { dev_info(dev, "Unable to map irq from device tree\n"); ipmi->irq = opal_event_request(prop); } if (request_irq(ipmi->irq, ipmi_opal_event, IRQ_TYPE_LEVEL_HIGH, "opal-ipmi", ipmi)) { dev_warn(dev, "Unable to request irq\n"); goto err_dispose; } ipmi->opal_msg = devm_kmalloc(dev, sizeof(*ipmi->opal_msg) + IPMI_MAX_MSG_LENGTH, GFP_KERNEL); if (!ipmi->opal_msg) { rc = -ENOMEM; goto err_unregister; } /* todo: query actual ipmi_device_id */ rc = ipmi_register_smi(&ipmi_powernv_smi_handlers, ipmi, &ipmi->ipmi_id, dev, 0); if (rc) { dev_warn(dev, "IPMI SMI registration failed (%d)\n", rc); goto err_free_msg; } dev_set_drvdata(dev, ipmi); return 0; err_free_msg: devm_kfree(dev, ipmi->opal_msg); err_unregister: free_irq(ipmi->irq, ipmi); err_dispose: irq_dispose_mapping(ipmi->irq); err_free: devm_kfree(dev, ipmi); return rc; }
/** * Enable fully-functional tablet mode and determine device parameters. * * @hdev: HID device */ static int huion_tablet_enable(struct hid_device *hdev) { int rc; struct usb_device *usb_dev = hid_to_usb_dev(hdev); struct huion_drvdata *drvdata = hid_get_drvdata(hdev); __le16 buf[6]; /* * Read string descriptor containing tablet parameters. The specific * string descriptor and data were discovered by sniffing the Windows * driver traffic. * NOTE: This enables fully-functional tablet mode. */ rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (USB_DT_STRING << 8) + 0x64, 0x0409, buf, sizeof(buf), USB_CTRL_GET_TIMEOUT); if (rc == -EPIPE) hid_warn(hdev, "device parameters not found\n"); else if (rc < 0) hid_warn(hdev, "failed to get device parameters: %d\n", rc); else if (rc != sizeof(buf)) hid_warn(hdev, "invalid device parameters\n"); else { s32 params[HUION_PH_ID_NUM]; s32 resolution; __u8 *p; s32 v; /* Extract device parameters */ params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]); params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]); params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]); resolution = le16_to_cpu(buf[5]); if (resolution == 0) { params[HUION_PH_ID_X_PM] = 0; params[HUION_PH_ID_Y_PM] = 0; } else { params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * 1000 / resolution; params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * 1000 / resolution; } /* Allocate fixed report descriptor */ drvdata->rdesc = devm_kmalloc(&hdev->dev, sizeof(huion_tablet_rdesc_template), GFP_KERNEL); if (drvdata->rdesc == NULL) { hid_err(hdev, "failed to allocate fixed rdesc\n"); return -ENOMEM; } drvdata->rsize = sizeof(huion_tablet_rdesc_template); /* Format fixed report descriptor */ memcpy(drvdata->rdesc, huion_tablet_rdesc_template, drvdata->rsize); for (p = drvdata->rdesc; p <= drvdata->rdesc + drvdata->rsize - 4;) { if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && p[3] < sizeof(params)) { v = params[p[3]]; put_unaligned(cpu_to_le32(v), (s32 *)p); p += 4; } else { p++; } } } return 0; }
static int ipmi_powernv_probe(struct platform_device *pdev) { struct ipmi_smi_powernv *ipmi; struct device *dev; u32 prop; int rc; if (!pdev || !pdev->dev.of_node) return -ENODEV; dev = &pdev->dev; ipmi = devm_kzalloc(dev, sizeof(*ipmi), GFP_KERNEL); if (!ipmi) return -ENOMEM; spin_lock_init(&ipmi->msg_lock); rc = of_property_read_u32(dev->of_node, "ibm,ipmi-interface-id", &prop); if (rc) { dev_warn(dev, "No interface ID property\n"); goto err_free; } ipmi->interface_id = prop; rc = of_property_read_u32(dev->of_node, "interrupts", &prop); if (rc) { dev_warn(dev, "No interrupts property\n"); goto err_free; } ipmi->event = 1ull << prop; ipmi->event_nb.notifier_call = ipmi_opal_event; rc = opal_notifier_register(&ipmi->event_nb); if (rc) { dev_warn(dev, "OPAL notifier registration failed (%d)\n", rc); goto err_free; } ipmi->opal_msg = devm_kmalloc(dev, sizeof(*ipmi->opal_msg) + IPMI_MAX_MSG_LENGTH, GFP_KERNEL); if (!ipmi->opal_msg) { rc = -ENOMEM; goto err_unregister; } /* todo: query actual ipmi_device_id */ rc = ipmi_register_smi(&ipmi_powernv_smi_handlers, ipmi, &ipmi->ipmi_id, dev, 0); if (rc) { dev_warn(dev, "IPMI SMI registration failed (%d)\n", rc); goto err_free_msg; } dev_set_drvdata(dev, ipmi); return 0; err_free_msg: devm_kfree(dev, ipmi->opal_msg); err_unregister: opal_notifier_unregister(&ipmi->event_nb); err_free: devm_kfree(dev, ipmi); return rc; }
/** * process_recv() - Received and parse incoming packet * @hid_ishtp_cl: Client instance to get stats * @recv_buf: Raw received host interface message * @data_len: length of the message * * Parse the incoming packet. If it is a response packet then it will update * per instance flags and wake up the caller waiting to for the response. */ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf, size_t data_len) { struct hostif_msg *recv_msg; unsigned char *payload; struct device_info *dev_info; int i, j; size_t payload_len, total_len, cur_pos; int report_type; struct report_list *reports_list; char *reports; size_t report_len; struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data; int curr_hid_dev = client_data->cur_hid_dev; if (data_len < sizeof(struct hostif_msg_hdr)) { dev_err(&client_data->cl_device->dev, "[hid-ish]: error, received %u which is less than data header %u\n", (unsigned int)data_len, (unsigned int)sizeof(struct hostif_msg_hdr)); ++client_data->bad_recv_cnt; ish_hw_reset(hid_ishtp_cl->dev); return; } payload = recv_buf + sizeof(struct hostif_msg_hdr); total_len = data_len; cur_pos = 0; do { recv_msg = (struct hostif_msg *)(recv_buf + cur_pos); payload_len = recv_msg->hdr.size; /* Sanity checks */ if (cur_pos + payload_len + sizeof(struct hostif_msg) > total_len) { ++client_data->bad_recv_cnt; report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos, payload_len); ish_hw_reset(hid_ishtp_cl->dev); break; } hid_ishtp_trace(client_data, "%s %d\n", __func__, recv_msg->hdr.command & CMD_MASK); switch (recv_msg->hdr.command & CMD_MASK) { case HOSTIF_DM_ENUM_DEVICES: if ((!(recv_msg->hdr.command & ~CMD_MASK) || client_data->init_done)) { ++client_data->bad_recv_cnt; report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos, payload_len); ish_hw_reset(hid_ishtp_cl->dev); break; } client_data->hid_dev_count = (unsigned int)*payload; if (!client_data->hid_devices) client_data->hid_devices = devm_kzalloc( &client_data->cl_device->dev, client_data->hid_dev_count * sizeof(struct device_info), GFP_KERNEL); if (!client_data->hid_devices) { dev_err(&client_data->cl_device->dev, "Mem alloc failed for hid device info\n"); wake_up_interruptible(&client_data->init_wait); break; } for (i = 0; i < client_data->hid_dev_count; ++i) { if (1 + sizeof(struct device_info) * i >= payload_len) { dev_err(&client_data->cl_device->dev, "[hid-ish]: [ENUM_DEVICES]: content size %lu is bigger than payload_len %u\n", 1 + sizeof(struct device_info) * i, (unsigned int)payload_len); } if (1 + sizeof(struct device_info) * i >= data_len) break; dev_info = (struct device_info *)(payload + 1 + sizeof(struct device_info) * i); if (client_data->hid_devices) memcpy(client_data->hid_devices + i, dev_info, sizeof(struct device_info)); } client_data->enum_devices_done = true; wake_up_interruptible(&client_data->init_wait); break; case HOSTIF_GET_HID_DESCRIPTOR: if ((!(recv_msg->hdr.command & ~CMD_MASK) || client_data->init_done)) { ++client_data->bad_recv_cnt; report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos, payload_len); ish_hw_reset(hid_ishtp_cl->dev); break; } if (!client_data->hid_descr[curr_hid_dev]) client_data->hid_descr[curr_hid_dev] = devm_kmalloc(&client_data->cl_device->dev, payload_len, GFP_KERNEL); if (client_data->hid_descr[curr_hid_dev]) { memcpy(client_data->hid_descr[curr_hid_dev], payload, payload_len); client_data->hid_descr_size[curr_hid_dev] = payload_len; client_data->hid_descr_done = true; } wake_up_interruptible(&client_data->init_wait); break; case HOSTIF_GET_REPORT_DESCRIPTOR: if ((!(recv_msg->hdr.command & ~CMD_MASK) || client_data->init_done)) { ++client_data->bad_recv_cnt; report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos, payload_len); ish_hw_reset(hid_ishtp_cl->dev); break; } if (!client_data->report_descr[curr_hid_dev]) client_data->report_descr[curr_hid_dev] = devm_kmalloc(&client_data->cl_device->dev, payload_len, GFP_KERNEL); if (client_data->report_descr[curr_hid_dev]) { memcpy(client_data->report_descr[curr_hid_dev], payload, payload_len); client_data->report_descr_size[curr_hid_dev] = payload_len; client_data->report_descr_done = true; } wake_up_interruptible(&client_data->init_wait); break; case HOSTIF_GET_FEATURE_REPORT: report_type = HID_FEATURE_REPORT; goto do_get_report; case HOSTIF_GET_INPUT_REPORT: report_type = HID_INPUT_REPORT; do_get_report: /* Get index of device that matches this id */ for (i = 0; i < client_data->num_hid_devices; ++i) { if (recv_msg->hdr.device_id == client_data->hid_devices[i].dev_id) if (client_data->hid_sensor_hubs[i]) { hid_input_report( client_data->hid_sensor_hubs[ i], report_type, payload, payload_len, 0); ishtp_hid_wakeup( client_data->hid_sensor_hubs[ i]); break; } } break; case HOSTIF_SET_FEATURE_REPORT: /* Get index of device that matches this id */ for (i = 0; i < client_data->num_hid_devices; ++i) { if (recv_msg->hdr.device_id == client_data->hid_devices[i].dev_id) if (client_data->hid_sensor_hubs[i]) { ishtp_hid_wakeup( client_data->hid_sensor_hubs[ i]); break; } } break; case HOSTIF_PUBLISH_INPUT_REPORT: report_type = HID_INPUT_REPORT; for (i = 0; i < client_data->num_hid_devices; ++i) if (recv_msg->hdr.device_id == client_data->hid_devices[i].dev_id) if (client_data->hid_sensor_hubs[i]) hid_input_report( client_data->hid_sensor_hubs[ i], report_type, payload, payload_len, 0); break; case HOSTIF_PUBLISH_INPUT_REPORT_LIST: report_type = HID_INPUT_REPORT; reports_list = (struct report_list *)payload; reports = (char *)reports_list->reports; for (j = 0; j < reports_list->num_of_reports; j++) { recv_msg = (struct hostif_msg *)(reports + sizeof(uint16_t)); report_len = *(uint16_t *)reports; payload = reports + sizeof(uint16_t) + sizeof(struct hostif_msg_hdr); payload_len = report_len - sizeof(struct hostif_msg_hdr); for (i = 0; i < client_data->num_hid_devices; ++i) if (recv_msg->hdr.device_id == client_data->hid_devices[i].dev_id && client_data->hid_sensor_hubs[i]) { hid_input_report( client_data->hid_sensor_hubs[ i], report_type, payload, payload_len, 0); } reports += sizeof(uint16_t) + report_len; } break; default: ++client_data->bad_recv_cnt; report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos, payload_len); ish_hw_reset(hid_ishtp_cl->dev); break; } if (!cur_pos && cur_pos + payload_len + sizeof(struct hostif_msg) < total_len) ++client_data->multi_packet_cnt; cur_pos += payload_len + sizeof(struct hostif_msg); payload += payload_len + sizeof(struct hostif_msg); } while (cur_pos < total_len); }
static int s2mps11_pmic_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = NULL; struct of_regulator_match *rdata = NULL; struct regulator_config config = { }; struct s2mps11_info *s2mps11; int i, ret = 0; const struct regulator_desc *regulators; s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), GFP_KERNEL); if (!s2mps11) return -ENOMEM; s2mps11->dev_type = platform_get_device_id(pdev)->driver_data; switch (s2mps11->dev_type) { case S2MPS11X: s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); regulators = s2mps11_regulators; break; case S2MPS13X: s2mps11->rdev_num = ARRAY_SIZE(s2mps13_regulators); regulators = s2mps13_regulators; break; case S2MPS14X: s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); regulators = s2mps14_regulators; break; case S2MPU02: s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators); regulators = s2mpu02_regulators; break; default: dev_err(&pdev->dev, "Invalid device type: %u\n", s2mps11->dev_type); return -EINVAL; }; s2mps11->ext_control_gpio = devm_kmalloc(&pdev->dev, sizeof(*s2mps11->ext_control_gpio) * s2mps11->rdev_num, GFP_KERNEL); if (!s2mps11->ext_control_gpio) return -ENOMEM; /* * 0 is a valid GPIO so initialize all GPIO-s to negative value * to indicate that external control won't be used for this regulator. */ for (i = 0; i < s2mps11->rdev_num; i++) s2mps11->ext_control_gpio[i] = -EINVAL; if (!iodev->dev->of_node) { if (iodev->pdata) { pdata = iodev->pdata; goto common_reg; } else { dev_err(pdev->dev.parent, "Platform data or DT node not supplied\n"); return -ENODEV; } } rdata = kzalloc(sizeof(*rdata) * s2mps11->rdev_num, GFP_KERNEL); if (!rdata) return -ENOMEM; for (i = 0; i < s2mps11->rdev_num; i++) rdata[i].name = regulators[i].name; ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11); if (ret) goto out; common_reg: platform_set_drvdata(pdev, s2mps11); config.dev = &pdev->dev; config.regmap = iodev->regmap_pmic; config.driver_data = s2mps11; config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH; config.ena_gpio_initialized = true; for (i = 0; i < s2mps11->rdev_num; i++) { struct regulator_dev *regulator; if (pdata) { config.init_data = pdata->regulators[i].initdata; config.of_node = pdata->regulators[i].reg_node; } else { config.init_data = rdata[i].init_data; config.of_node = rdata[i].of_node; } config.ena_gpio = s2mps11->ext_control_gpio[i]; regulator = devm_regulator_register(&pdev->dev, ®ulators[i], &config); if (IS_ERR(regulator)) { ret = PTR_ERR(regulator); dev_err(&pdev->dev, "regulator init failed for %d\n", i); goto out; } if (gpio_is_valid(s2mps11->ext_control_gpio[i])) { ret = s2mps14_pmic_enable_ext_control(s2mps11, regulator); if (ret < 0) { dev_err(&pdev->dev, "failed to enable GPIO control over %s: %d\n", regulator->desc->name, ret); goto out; } } } out: kfree(rdata); return ret; }
static int bman_portal_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct bm_portal_config *pcfg; struct resource *addr_phys[2]; void __iomem *va; int irq, cpu; pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL); if (!pcfg) return -ENOMEM; pcfg->dev = dev; addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM, DPAA_PORTAL_CE); if (!addr_phys[0]) { dev_err(dev, "Can't get %s property 'reg::CE'\n", node->full_name); return -ENXIO; } addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM, DPAA_PORTAL_CI); if (!addr_phys[1]) { dev_err(dev, "Can't get %s property 'reg::CI'\n", node->full_name); return -ENXIO; } pcfg->cpu = -1; irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_err(dev, "Can't get %s IRQ'\n", node->full_name); return -ENXIO; } pcfg->irq = irq; va = ioremap_prot(addr_phys[0]->start, resource_size(addr_phys[0]), 0); if (!va) { dev_err(dev, "ioremap::CE failed\n"); goto err_ioremap1; } pcfg->addr_virt[DPAA_PORTAL_CE] = va; va = ioremap_prot(addr_phys[1]->start, resource_size(addr_phys[1]), _PAGE_GUARDED | _PAGE_NO_CACHE); if (!va) { dev_err(dev, "ioremap::CI failed\n"); goto err_ioremap2; } pcfg->addr_virt[DPAA_PORTAL_CI] = va; spin_lock(&bman_lock); cpu = cpumask_next_zero(-1, &portal_cpus); if (cpu >= nr_cpu_ids) { /* unassigned portal, skip init */ spin_unlock(&bman_lock); return 0; } cpumask_set_cpu(cpu, &portal_cpus); spin_unlock(&bman_lock); pcfg->cpu = cpu; if (!init_pcfg(pcfg)) { dev_err(dev, "portal init failed\n"); goto err_portal_init; } /* clear irq affinity if assigned cpu is offline */ if (!cpu_online(cpu)) bman_offline_cpu(cpu); return 0; err_portal_init: iounmap(pcfg->addr_virt[DPAA_PORTAL_CI]); err_ioremap2: iounmap(pcfg->addr_virt[DPAA_PORTAL_CE]); err_ioremap1: return -ENXIO; }