static int sc8800_rx(struct sc8800_data *sc8800) { int ret = 0, len, real_len; struct bp_head packet; char *buf = NULL; ap_rdy(sc8800,0); ret = ap_get_head(sc8800, &packet); if(ret < 0){ dev_err(sc8800->dev, "ERR: %s ap_get_head err = %d\n", __func__, ret); goto out; } len = packet.length; if(len > BP_PACKET_DATA_LEN) real_len = (((len -BP_PACKET_DATA_LEN-1)/BP_PACKET_SIZE)+2)*BP_PACKET_SIZE; else real_len = BP_PACKET_SIZE; if(len > RD_BUF_SIZE){ dev_err(sc8800->dev, "ERR: %s len[%d] is large than buffer size[%lu]\n", __func__, real_len, RD_BUF_SIZE); goto out; } buf = kzalloc(real_len, GFP_KERNEL); if(!buf){ dev_err(sc8800->dev,"ERR: %s no memmory for rx_buf\n", __func__); goto out; } memcpy(buf, packet.data, BP_PACKET_DATA_LEN); if(len > BP_PACKET_DATA_LEN) spi_out(sc8800, buf + BP_PACKET_DATA_LEN, real_len-BP_PACKET_SIZE, &ret); if(ret < 0){ dev_err(sc8800->dev, "ERR: %s spi out err = %d\n", __func__, ret); goto out; } spin_lock(&sc8800->lock); if(sc8800->rx_len + len > RD_BUF_SIZE){ dev_warn(sc8800->dev, "WARN: %s read buffer is full\n", __func__); }else { memcpy(sc8800->rx_buf+sc8800->rx_len, buf, len); sc8800->rx_len += len; } spin_unlock(&sc8800->lock); sc8800_dbg(sc8800->dev, "%s rx_len = %d\n", __func__, sc8800->rx_len); ret = sc8800->rx_len; out: ap_rdy(sc8800,1); if(buf) kfree(buf); buf = NULL; return ret; }
static int wmt_ebm_probe(struct platform_device *pdev) { int err = 0; struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wmt_ebm_regs = (struct ebm_dev_reg_s *)res->start; /*init clock*/ init_clock(); /*init GPIO*/ init_ebm_gpio_func(); err = request_irq(IRQ_PMC_MDM_RDY, mdm_rdy_handler, IRQF_DISABLED, "mdm_rdy" , NULL); if(err){ printk("PMC_MDM_RDY request irq failed!"); goto exit_err; } err = request_irq(IRQ_PMC_EBM_WAKEREQ, ebm_wakereq_handler, IRQF_DISABLED, "ebm_wake_req" , NULL); if(err){ printk("PMC_EBM_WAKEREQ request irq failed!"); goto exit_err; } err = request_irq(IRQ_PMC_MDM_WAKE_AP, mdm_wake_ap_handler, IRQF_DISABLED, "mdm_wake_ap" , NULL); if(err){ printk("PMC_MDM_WAKE_AP request irq failed!"); goto exit_err; } init_irq_type(); enable_ebm_irq(1); ap_rdy(1); ebm_wake_ack(1); wmt_ebm_regs->EbmBaseAddr = firmware_base_addr; wmt_ebm_regs->EbmcOnOff = 0x1; #ifdef CONFIG_PM register_syscore_ops(&wmt_ebm_syscore_ops); #endif return 0; exit_err: return err; }