static int nokia_modem_remove(struct device *dev) { struct nokia_modem_device *modem = dev_get_drvdata(dev); if (!modem) return 0; if (modem->ssi_protocol) { hsi_remove_client(&modem->ssi_protocol->device, NULL); modem->ssi_protocol = NULL; } nokia_modem_gpio_unexport(dev); dev_set_drvdata(dev, NULL); disable_irq_wake(modem->nokia_modem_rst_ind_irq); tasklet_kill(&modem->nokia_modem_rst_ind_tasklet); return 0; }
static int nokia_modem_probe(struct device *dev) { struct device_node *np; struct nokia_modem_device *modem; struct hsi_client *cl = to_hsi_client(dev); struct hsi_port *port = hsi_get_port(cl); int irq, pflags, err; struct hsi_board_info ssip; struct hsi_board_info cmtspeech; np = dev->of_node; if (!np) { dev_err(dev, "device tree node not found\n"); return -ENXIO; } modem = devm_kzalloc(dev, sizeof(*modem), GFP_KERNEL); if (!modem) { dev_err(dev, "Could not allocate memory for nokia_modem_device\n"); return -ENOMEM; } dev_set_drvdata(dev, modem); modem->device = dev; irq = irq_of_parse_and_map(np, 0); if (!irq) { dev_err(dev, "Invalid rst_ind interrupt (%d)\n", irq); return -EINVAL; } modem->nokia_modem_rst_ind_irq = irq; pflags = irq_get_trigger_type(irq); tasklet_init(&modem->nokia_modem_rst_ind_tasklet, do_nokia_modem_rst_ind_tasklet, (unsigned long)modem); err = devm_request_irq(dev, irq, nokia_modem_rst_ind_isr, pflags, "modem_rst_ind", modem); if (err < 0) { dev_err(dev, "Request rst_ind irq(%d) failed (flags %d)\n", irq, pflags); return err; } enable_irq_wake(irq); if(pm) { err = nokia_modem_gpio_probe(dev); if (err < 0) { dev_err(dev, "Could not probe GPIOs\n"); goto error1; } } ssip.name = "ssi-protocol"; ssip.tx_cfg = cl->tx_cfg; ssip.rx_cfg = cl->rx_cfg; ssip.platform_data = NULL; ssip.archdata = NULL; modem->ssi_protocol = hsi_new_client(port, &ssip); if (!modem->ssi_protocol) { dev_err(dev, "Could not register ssi-protocol device\n"); err = -ENOMEM; goto error2; } err = device_attach(&modem->ssi_protocol->device); if (err == 0) { dev_dbg(dev, "Missing ssi-protocol driver\n"); err = -EPROBE_DEFER; goto error3; } else if (err < 0) { dev_err(dev, "Could not load ssi-protocol driver (%d)\n", err); goto error3; } cmtspeech.name = "cmt-speech"; cmtspeech.tx_cfg = cl->tx_cfg; cmtspeech.rx_cfg = cl->rx_cfg; cmtspeech.platform_data = NULL; cmtspeech.archdata = NULL; modem->cmt_speech = hsi_new_client(port, &cmtspeech); if (!modem->cmt_speech) { dev_err(dev, "Could not register cmt-speech device\n"); err = -ENOMEM; goto error3; } err = device_attach(&modem->cmt_speech->device); if (err == 0) { dev_dbg(dev, "Missing cmt-speech driver\n"); err = -EPROBE_DEFER; goto error4; } else if (err < 0) { dev_err(dev, "Could not load cmt-speech driver (%d)\n", err); goto error4; } dev_info(dev, "Registered Nokia HSI modem\n"); return 0; error4: hsi_remove_client(&modem->cmt_speech->device, NULL); error3: hsi_remove_client(&modem->ssi_protocol->device, NULL); error2: nokia_modem_gpio_unexport(dev); error1: disable_irq_wake(modem->nokia_modem_rst_ind_irq); tasklet_kill(&modem->nokia_modem_rst_ind_tasklet); return err; }