Ejemplo n.º 1
0
static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
	const struct firmware *firmware;
	struct rt_firmware *pfirmware = NULL;
	int err = 0;
	u16 earlyrxthreshold = 7;

	rtlpriv->dm.dm_initialgain_enable = 1;
	rtlpriv->dm.dm_flag = 0;
	rtlpriv->dm.disable_framebursting = 0;
	rtlpriv->dm.thermalvalue = 0;
	rtlpriv->dm.useramask = true;

	/* compatible 5G band 91se just 2.4G band & smsp */
	rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
	rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
	rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;

	rtlpci->transmit_config = 0;

	rtlpci->receive_config =
			RCR_APPFCS |
			RCR_APWRMGT |
			/*RCR_ADD3 |*/
			RCR_AMF	|
			RCR_ADF |
			RCR_APP_MIC |
			RCR_APP_ICV |
			RCR_AICV |
			/* Accept ICV error, CRC32 Error */
			RCR_ACRC32 |
			RCR_AB |
			/* Accept Broadcast, Multicast */
			RCR_AM	|
			/* Accept Physical match */
			RCR_APM |
			/* Accept Destination Address packets */
			/*RCR_AAP |*/
			RCR_APP_PHYST_STAFF |
			/* Accept PHY status */
			RCR_APP_PHYST_RXFF |
			(earlyrxthreshold << RCR_FIFO_OFFSET);

	rtlpci->irq_mask[0] = (u32)
			(IMR_ROK |
			IMR_VODOK |
			IMR_VIDOK |
			IMR_BEDOK |
			IMR_BKDOK |
			IMR_HCCADOK |
			IMR_MGNTDOK |
			IMR_COMDOK |
			IMR_HIGHDOK |
			IMR_BDOK |
			IMR_RXCMDOK |
			/*IMR_TIMEOUT0 |*/
			IMR_RDU |
			IMR_RXFOVW	|
			IMR_BCNINT
			/*| IMR_TXFOVW*/
			/*| IMR_TBDOK |
			IMR_TBDER*/);

	rtlpci->irq_mask[1] = (u32) 0;

	rtlpci->shortretry_limit = 0x30;
	rtlpci->longretry_limit = 0x30;

	rtlpci->first_init = true;

	/* for LPS & IPS */
	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
	rtlpriv->psc.reg_fwctrl_lps = 3;
	rtlpriv->psc.reg_max_lps_awakeintvl = 5;
	/* for ASPM, you can close aspm through
	 * set const_support_pciaspm = 0 */
	rtl92s_init_aspm_vars(hw);

	if (rtlpriv->psc.reg_fwctrl_lps == 1)
		rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
	else if (rtlpriv->psc.reg_fwctrl_lps == 2)
		rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
	else if (rtlpriv->psc.reg_fwctrl_lps == 3)
		rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;

	/* for firmware buf */
	rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware));
	if (!rtlpriv->rtlhal.pfirmware) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("Can't alloc buffer for fw.\n"));
		return 1;
	}

	printk(KERN_INFO "rtl8192se: Driver for Realtek RTL8192SE/RTL8191SE\n"
	       "           Loading firmware %s\n", rtlpriv->cfg->fw_name);
	/* request fw */
	err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
			rtlpriv->io.dev);
	if (err) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("Failed to request firmware!\n"));
		return 1;
	}
	if (firmware->size > sizeof(struct rt_firmware)) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("Firmware is too big!\n"));
		release_firmware(firmware);
		return 1;
	}

	pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
	memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
	pfirmware->sz_fw_tmpbufferlen = firmware->size;
	release_firmware(firmware);

	return err;
}
Ejemplo n.º 2
0
static int __devinit omapl_pru_can_probe(struct platform_device *pdev)
{
	struct net_device *ndev = NULL;
	struct omapl_pru_can_priv *priv = NULL;
	struct ti_pru_can_platform_data *pdata;
	struct resource *res_mem, *trx_irq;
	pru_can_firmware_structure fw_pru;
	u32 err, retries = 0;

	pdata = pdev->dev.platform_data;
	if (!pdata) {
		dev_err(&pdev->dev, "no platform data provided for pru!\n");
		return -ENODEV;
	}

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res_mem) {
		dev_err(&pdev->dev, "unable to get pru memory resources!\n");
		err = -ENODEV;
		goto probe_exit;
	}

	trx_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!trx_irq) {
		dev_err(&pdev->dev, "unable to get pru interrupt resources!\n");
		err = -ENODEV;
		goto probe_exit;
	}

	if (!request_mem_region(res_mem->start, resource_size(res_mem),
				dev_name(&pdev->dev))) {
		dev_err(&pdev->dev, "pru memory region already claimed!\n");
		err = -EBUSY;
		goto probe_exit;
	}

	ndev = alloc_candev(sizeof(struct omapl_pru_can_priv), MB_MAX + 1);
	if (!ndev) {
		dev_err(&pdev->dev, "alloc_candev failed\n");
		err = -ENOMEM;
		goto probe_exit_free_region;
	}
	priv = netdev_priv(ndev);

	priv->pru_arm_iomap.pru_io_addr =
	    ioremap(res_mem->start, resource_size(res_mem));
	if (!priv->pru_arm_iomap.pru_io_addr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto probe_exit_free_region;
	}

	priv->pru_arm_iomap.psc0_io_addr = IO_ADDRESS(DA8XX_PSC0_BASE);
	if (!priv->pru_arm_iomap.psc0_io_addr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto probe_exit_iounmap;
	}

	priv->pru_arm_iomap.psc1_io_addr = IO_ADDRESS(DA8XX_PSC1_BASE);
	if (!priv->pru_arm_iomap.psc1_io_addr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto probe_exit_iounmap;
	}

	priv->pru_arm_iomap.syscfg_io_addr = IO_ADDRESS(DA8XX_SYSCFG0_BASE);
	if (!priv->pru_arm_iomap.syscfg_io_addr) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -ENOMEM;
		goto probe_exit_iounmap;
	}

	priv->ndev = ndev;
	priv->trx_irq = trx_irq->start;

	priv->can.bittiming_const = NULL;
	priv->can.do_set_bittiming = omapl_pru_can_set_bittiming;
	priv->can.do_set_mode = omapl_pru_can_set_mode;
	priv->can.do_get_state = omapl_pru_can_get_state;
	priv->can_tx_hndl.u8prunumber = CAN_TX_PRU_1;
	priv->can_rx_hndl.u8prunumber = CAN_RX_PRU_0;

	ndev->flags |= (IFF_ECHO | IFF_NOARP);	/* we support local echo, no arp */
	platform_set_drvdata(pdev, ndev);
	SET_NETDEV_DEV(ndev, &pdev->dev);
	ndev->netdev_ops = &omapl_pru_can_netdev_ops;

	priv->clk = clk_get(&pdev->dev, "pru_ck");
	if (IS_ERR(priv->clk)) {
		dev_err(&pdev->dev, "no clock available\n");
		err = PTR_ERR(priv->clk);
		priv->clk = NULL;
		goto probe_exit_candev;
	}
	priv->can.clock.freq = clk_get_rate(priv->clk);

	priv->clk_timer = clk_get(&pdev->dev, "pll1_sysclk2");
	if (IS_ERR(priv->clk_timer)) {
		dev_err(&pdev->dev, "no timer clock available\n");
		err = PTR_ERR(priv->clk_timer);
		priv->clk_timer = NULL;
		goto probe_exit_candev;
	}
	priv->timer_freq = clk_get_rate(priv->clk_timer);

	err = register_candev(ndev);
	if (err) {
		dev_err(&pdev->dev, "register_candev() failed\n");
		err = -ENODEV;
		goto probe_exit_clk;
	}

	err = request_firmware(&priv->fw_tx, "PRU_CAN_Emulation_Tx.bin",
			       &pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "can't load firmware\n");
		err = -ENODEV;
		goto probe_exit_clk;
	}

	dev_info(&pdev->dev, "fw_tx size %d. downloading...\n",
		 priv->fw_tx->size);

	err = request_firmware(&priv->fw_rx, "PRU_CAN_Emulation_Rx.bin",
			       &pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "can't load firmware\n");
		err = -ENODEV;
		goto probe_release_fw;
	}
	dev_info(&pdev->dev, "fw_rx size %d. downloading...\n",
		 priv->fw_rx->size);

	fw_pru.ptr_pru1 = kmalloc(priv->fw_tx->size, GFP_KERNEL);
	memcpy((void *)fw_pru.ptr_pru1, (const void *)priv->fw_tx->data,
	       priv->fw_tx->size);
	fw_pru.u32_pru1_code_size = priv->fw_tx->size;
	fw_pru.ptr_pru0 = kmalloc(priv->fw_rx->size, GFP_KERNEL);
	memcpy((void *)fw_pru.ptr_pru0, (const void *)priv->fw_rx->data,
	       priv->fw_rx->size);
	fw_pru.u32_pru0_code_size = priv->fw_rx->size;

	/* init the pru */
	pru_can_emulation_init(&priv->pru_arm_iomap, priv->can.clock.freq);

	while ((pru_can_check_init_status()) && (retries++ < MAX_INIT_RETRIES))
		udelay(retries);

	if (MAX_INIT_RETRIES <= retries) {
		dev_err(&pdev->dev, "failed to initialize the pru\n");
		err = -ENODEV;
		goto probe_release_fw_1;
	}

	pru_can_enable();
	/* download firmware into pru */
	err = pru_can_download_firmware(&fw_pru, 0);
	if (err) {
		dev_err(&pdev->dev, "firmware download error\n");
		err = -ENODEV;
		goto probe_release_fw_1;
	}
	err = pru_can_download_firmware(&fw_pru, 1);
	if (err) {
		dev_err(&pdev->dev, "firmware download error\n");
		err = -ENODEV;
		goto probe_release_fw_1;
	}

	if (pru_can_calculatetiming (DFLT_PRU_FREQ, DFLT_PRU_BITRATE) != 0) {
        return -EINVAL;
    }

	pru_can_run(0);
	pru_can_run(1);
	kfree((const void *)fw_pru.ptr_pru0);
	kfree((const void *)fw_pru.ptr_pru1);

	/*Create The Work Queue */
	if ((priv->pru_can_wQ =
	     create_freezeable_workqueue("omapl_pru_wQ")) == NULL)
		dev_err(&pdev->dev, "failed to create work queue\n");

	INIT_WORK(&priv->rx_work, omapl_pru_can_rx_wQ);
	dev_info(&pdev->dev,
		 "%s device registered"
		 "(&reg_base=0x%p, trx_irq = %d,  clk = %d)\n",
		 DRV_NAME, priv->pru_arm_iomap.pru_io_addr, priv->trx_irq,
		 priv->can.clock.freq);
	return 0;

probe_release_fw_1:
	kfree((const void *)fw_pru.ptr_pru0);
	kfree((const void *)fw_pru.ptr_pru1);
	release_firmware(priv->fw_rx);
probe_release_fw:
	release_firmware(priv->fw_tx);
probe_exit_clk:
	clk_put(priv->clk);
probe_exit_candev:
	if (NULL != ndev)
		free_candev(ndev);
probe_exit_iounmap:
	iounmap(priv->pru_arm_iomap.pru_io_addr);
probe_exit_free_region:
	release_mem_region(res_mem->start, resource_size(res_mem));
probe_exit:
	return err;
}
Ejemplo n.º 3
0
static int __devinit p54p_probe(struct pci_dev *pdev,
                                const struct pci_device_id *id)
{
    struct p54p_priv *priv;
    struct ieee80211_hw *dev;
    unsigned long mem_addr, mem_len;
    int err;

    err = pci_enable_device(pdev);
    if (err) {
        dev_err(&pdev->dev, "Cannot enable new PCI device\n");
        return err;
    }

    mem_addr = pci_resource_start(pdev, 0);
    mem_len = pci_resource_len(pdev, 0);
    if (mem_len < sizeof(struct p54p_csr)) {
        dev_err(&pdev->dev, "Too short PCI resources\n");
        goto err_disable_dev;
    }

    err = pci_request_regions(pdev, "p54pci");
    if (err) {
        dev_err(&pdev->dev, "Cannot obtain PCI resources\n");
        goto err_disable_dev;
    }

    if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
            pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
        dev_err(&pdev->dev, "No suitable DMA available\n");
        goto err_free_reg;
    }

    pci_set_master(pdev);
    pci_try_set_mwi(pdev);

    pci_write_config_byte(pdev, 0x40, 0);
    pci_write_config_byte(pdev, 0x41, 0);

    dev = p54_init_common(sizeof(*priv));
    if (!dev) {
        dev_err(&pdev->dev, "ieee80211 alloc failed\n");
        err = -ENOMEM;
        goto err_free_reg;
    }

    priv = dev->priv;
    priv->pdev = pdev;

    SET_IEEE80211_DEV(dev, &pdev->dev);
    pci_set_drvdata(pdev, dev);

    priv->map = ioremap(mem_addr, mem_len);
    if (!priv->map) {
        dev_err(&pdev->dev, "Cannot map device memory\n");
        err = -ENOMEM;
        goto err_free_dev;
    }

    priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
                         &priv->ring_control_dma);
    if (!priv->ring_control) {
        dev_err(&pdev->dev, "Cannot allocate rings\n");
        err = -ENOMEM;
        goto err_iounmap;
    }
    priv->common.open = p54p_open;
    priv->common.stop = p54p_stop;
    priv->common.tx = p54p_tx;

    spin_lock_init(&priv->lock);
    tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev);

    err = request_firmware(&priv->firmware, "isl3886pci",
                           &priv->pdev->dev);
    if (err) {
        dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
        err = request_firmware(&priv->firmware, "isl3886",
                               &priv->pdev->dev);
        if (err)
            goto err_free_common;
    }

    err = p54p_open(dev);
    if (err)
        goto err_free_common;
    err = p54_read_eeprom(dev);
    p54p_stop(dev);
    if (err)
        goto err_free_common;

    err = p54_register_common(dev, &pdev->dev);
    if (err)
        goto err_free_common;

    return 0;

err_free_common:
    release_firmware(priv->firmware);
    pci_free_consistent(pdev, sizeof(*priv->ring_control),
                        priv->ring_control, priv->ring_control_dma);

err_iounmap:
    iounmap(priv->map);

err_free_dev:
    pci_set_drvdata(pdev, NULL);
    p54_free_common(dev);

err_free_reg:
    pci_release_regions(pdev);
err_disable_dev:
    pci_disable_device(pdev);
    return err;
}
Ejemplo n.º 4
0
static int load_kernel_fw_bootmode(struct spi_device *spi, const char *pFn)
{
	const struct firmware *fw = NULL;
	int remaining;
	unsigned int uPos = 0;
	unsigned int fw_addr = STM_APP_ADDR;
	int iRet;
	int block = STM_MAX_XFER_SIZE;
	int count = 0;
	int err_count = 0;
	int retry_count = 0;

	pr_info("[SSP] ssp_load_fw start!!!\n");

	iRet = request_firmware(&fw, pFn, &spi->dev);
	if (iRet) {
		pr_err("[SSP] Unable to open firmware %s\n", pFn);
		return iRet;
	}

	remaining = fw->size;
	while (remaining > 0) {
		if (block > remaining)
			block = remaining;

		while (retry_count < 3) {
			iRet = fw_write_stm(spi, fw_addr, block, fw->data + uPos);
			if (iRet < block) {
				pr_err("[SSP] Error writing to addr 0x%08X\n", fw_addr);
				if (iRet < 0) {
					pr_err("[SSP] Erro was %d\n", iRet);
				} else {
					pr_err("[SSP] Incomplete write of %d bytes\n",
						iRet);
					iRet = -EIO;
				}
				retry_count++;
				err_count++;
			} else {
				retry_count = 0;
				break;
			}
		}
		if (iRet < 0) {
			pr_err("[SSP] Writing MEM failed: %d, retry cont: %d\n", iRet, err_count);
			goto out_load_kernel;
		}
		remaining -= block;
		uPos += block;
		fw_addr += block;
		if (count++ == 20) {
			pr_info("[SSP] Updated %u bytes / %u bytes\n", uPos,
				fw->size);
			count = 0;
		}
	}

	pr_info("[SSP] Firmware download is success.(%d bytes, retry %d)\n", uPos, err_count);

out_load_kernel:
	release_firmware(fw);
	return iRet;
}
Ejemplo n.º 5
0
static void load_code(struct icom_port *icom_port)
{
	const struct firmware *fw;
	char __iomem *iram_ptr;
	int index;
	int status = 0;
	void __iomem *dram_ptr = icom_port->dram;
	dma_addr_t temp_pci;
	unsigned char *new_page = NULL;
	unsigned char cable_id = NO_CABLE;
	struct pci_dev *dev = icom_port->adapter->pci_dev;

	/* Clear out any pending interrupts */
	writew(0x3FFF, icom_port->int_reg);

	trace(icom_port, "CLEAR_INTERRUPTS", 0);

	/* Stop processor */
	stop_processor(icom_port);

	/* Zero out DRAM */
	memset_io(dram_ptr, 0, 512);

	/* Load Call Setup into Adapter */
	if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
		dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
		status = -1;
		goto load_code_exit;
	}

	if (fw->size > ICOM_DCE_IRAM_OFFSET) {
		dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
		release_firmware(fw);
		status = -1;
		goto load_code_exit;
	}

	iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
	for (index = 0; index < fw->size; index++)
		writeb(fw->data[index], &iram_ptr[index]);

	release_firmware(fw);

	/* Load Resident DCE portion of Adapter */
	if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
		dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
		status = -1;
		goto load_code_exit;
	}

	if (fw->size > ICOM_IRAM_SIZE) {
		dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
		release_firmware(fw);
		status = -1;
		goto load_code_exit;
	}

	iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
	for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
		writeb(fw->data[index], &iram_ptr[index]);

	release_firmware(fw);

	/* Set Hardware level */
	if (icom_port->adapter->version == ADAPTER_V2)
		writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));

	/* Start the processor in Adapter */
	start_processor(icom_port);

	writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
	       &(icom_port->dram->HDLCConfigReg));
	writeb(0x04, &(icom_port->dram->FlagFillIdleTimer));	/* 0.5 seconds */
	writeb(0x00, &(icom_port->dram->CmdReg));
	writeb(0x10, &(icom_port->dram->async_config3));
	writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
		ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));

	/*Set up data in icom DRAM to indicate where personality
	 *code is located and its length.
	 */
	new_page = pci_alloc_consistent(dev, 4096, &temp_pci);

	if (!new_page) {
		dev_err(&dev->dev, "Can not allocate DMA buffer\n");
		status = -1;
		goto load_code_exit;
	}

	if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
		dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
		status = -1;
		goto load_code_exit;
	}

	if (fw->size > ICOM_DCE_IRAM_OFFSET) {
		dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
		release_firmware(fw);
		status = -1;
		goto load_code_exit;
	}

	for (index = 0; index < fw->size; index++)
		new_page[index] = fw->data[index];

	release_firmware(fw);

	writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
	writel(temp_pci, &icom_port->dram->mac_load_addr);

	/*Setting the syncReg to 0x80 causes adapter to start downloading
	   the personality code into adapter instruction RAM.
	   Once code is loaded, it will begin executing and, based on
	   information provided above, will start DMAing data from
	   shared memory to adapter DRAM.
	 */
	/* the wait loop below verifies this write operation has been done
	   and processed
	*/
	writeb(START_DOWNLOAD, &icom_port->dram->sync);

	/* Wait max 1 Sec for data download and processor to start */
	for (index = 0; index < 10; index++) {
		msleep(100);
		if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
			break;
	}

	if (index == 10)
		status = -1;

	/*
	 * check Cable ID
	 */
	cable_id = readb(&icom_port->dram->cable_id);

	if (cable_id & ICOM_CABLE_ID_VALID) {
		/* Get cable ID into the lower 4 bits (standard form) */
		cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
		icom_port->cable_id = cable_id;
	} else {
Ejemplo n.º 6
0
static int kgsl_ringbuffer_load_pfp_ucode(struct kgsl_device *device)
{
	int status = 0;
	int i;
	const struct firmware *fw = NULL;
	unsigned int *fw_ptr = NULL;
	size_t fw_word_size = 0;
	struct kgsl_yamato_device *yamato_device = KGSL_YAMATO_DEVICE(device);

	if (yamato_device->pfp_fw == NULL) {
		if (device->chip_id == KGSL_CHIPID_LEIA_REV470) {
			status = request_firmware(&fw, LEIA_PFP_470_FW,
				device->dev);
			if (status != 0) {
				KGSL_DRV_ERR("request_firmware for %s \
					 failed with error %d\n",
					LEIA_PFP_470_FW, status);
				return status;
			}
		} else {
			status = request_firmware(&fw, YAMATO_PFP_FW,
				device->dev);
			if (status != 0) {
				KGSL_DRV_ERR("request_firmware for %s \
					 failed with error %d\n",
					YAMATO_PFP_FW, status);
				return status;
			}
		}
		/*this firmware must come in 1 word chunks. */
		if ((fw->size % sizeof(uint32_t)) != 0) {
			KGSL_DRV_ERR("bad firmware size %d.\n", fw->size);
			status = -EINVAL;
			goto error_release_fw;
		}
		fw_ptr = (unsigned int *)fw->data;
		fw_word_size = fw->size/sizeof(uint32_t);
		yamato_device->pfp_fw_size = fw_word_size;

		/* keep a copy of fw to be reloaded  later */
		yamato_device->pfp_fw = (unsigned int *)
						kmalloc(fw->size, GFP_KERNEL);
		if (yamato_device->pfp_fw == NULL) {
			KGSL_DRV_ERR("ERROR: couldn't kmalloc fw size= %d.\n",
								fw->size);
			status = -EINVAL;
			goto error_release_fw;
		}
		memcpy(yamato_device->pfp_fw, fw->data, fw->size);

	} else {
		fw_ptr = yamato_device->pfp_fw;
		fw_word_size = yamato_device->pfp_fw_size;
	}

	KGSL_DRV_INFO("loading pfp ucode version: %d\n", fw_ptr[0]);

	kgsl_yamato_regwrite(device, REG_CP_PFP_UCODE_ADDR, 0);
	for (i = 1; i < fw_word_size; i++)
		kgsl_yamato_regwrite(device, REG_CP_PFP_UCODE_DATA, fw_ptr[i]);

error_release_fw:
	if (fw)
		release_firmware(fw);
	return status;
}
Ejemplo n.º 7
0
int cx18_av_loadfw(struct cx18 *cx)
{
	struct v4l2_subdev *sd = &cx->av_state.sd;
	const struct firmware *fw = NULL;
	u32 size;
	u32 u, v;
	const u8 *ptr;
	int i;
	int retries1 = 0;

	if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
		CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE);
		return -EINVAL;
	}

	/* The firmware load often has byte errors, so allow for several
	   retries, both at byte level and at the firmware load level. */
	while (retries1 < 5) {
		cx18_av_write4_expect(cx, CXADEC_CHIP_CTRL, 0x00010000,
					  0x00008430, 0xffffffff); /* cx25843 */
		cx18_av_write_expect(cx, CXADEC_STD_DET_CTL, 0xf6, 0xf6, 0xff);

		/* Reset the Mako core, Register is alias of CXADEC_CHIP_CTRL */
		cx18_av_write4_expect(cx, 0x8100, 0x00010000,
					  0x00008430, 0xffffffff); /* cx25843 */

		/* Put the 8051 in reset and enable firmware upload */
		cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000);

		ptr = fw->data;
		size = fw->size;

		for (i = 0; i < size; i++) {
			u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
			u32 value = 0;
			int retries2;
			int unrec_err = 0;

			for (retries2 = 0; retries2 < CX18_MAX_MMIO_WR_RETRIES;
			     retries2++) {
				cx18_av_write4_noretry(cx, CXADEC_DL_CTL,
						       dl_control);
				udelay(10);
				value = cx18_av_read4(cx, CXADEC_DL_CTL);
				if (value == dl_control)
					break;
				/* Check if we can correct the byte by changing
				   the address.  We can only write the lower
				   address byte of the address. */
				if ((value & 0x3F00) != (dl_control & 0x3F00)) {
					unrec_err = 1;
					break;
				}
			}
			if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES)
				break;
		}
		if (i == size)
			break;
		retries1++;
	}
	if (retries1 >= 5) {
		CX18_ERR_DEV(sd, "unable to load firmware %s\n", FWFILE);
		release_firmware(fw);
		return -EIO;
	}

	cx18_av_write4_expect(cx, CXADEC_DL_CTL,
				0x03000000 | fw->size, 0x03000000, 0x13000000);

	CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);

	if (cx18_av_verifyfw(cx, fw) == 0)
		cx18_av_write4_expect(cx, CXADEC_DL_CTL,
				0x13000000 | fw->size, 0x13000000, 0x13000000);

	/* Output to the 416 */
	cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);

	/* Audio input control 1 set to Sony mode */
	/* Audio output input 2 is 0 for slave operation input */
	/* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
	/* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
	   after WS transition for first bit of audio word. */
	cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0);

	/* Audio output control 1 is set to Sony mode */
	/* Audio output control 2 is set to 1 for master mode */
	/* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
	/* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
	   after WS transition for first bit of audio word. */
	/* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT
	   are generated) */
	cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);

	/* set alt I2s master clock to /0x16 and enable alt divider i2s
	   passthrough */
	cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687);

	cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
								  0x3F00FFFF);
	/* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */

	/* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
	/* Register 0x09CC is defined by the Merlin firmware, and doesn't
	   have a name in the spec. */
	cx18_av_write4(cx, 0x09CC, 1);

	v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
	/* If bit 11 is 1, clear bit 10 */
	if (v & 0x800)
		cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
				      0, 0x400);

	/* Toggle the AI1 MUX */
	v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
	u = v & CX18_AI1_MUX_MASK;
	v &= ~CX18_AI1_MUX_MASK;
	if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
		/* Switch to I2S1 */
		v |= CX18_AI1_MUX_I2S1;
		cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
				      v, CX18_AI1_MUX_MASK);
		/* Switch back to the A/V decoder core I2S output */
		v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
	} else {
		/* Switch to the A/V decoder core I2S output */
		v |= CX18_AI1_MUX_843_I2S;
		cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
				      v, CX18_AI1_MUX_MASK);
		/* Switch back to I2S1 or I2S2 */
		v = (v & ~CX18_AI1_MUX_MASK) | u;
	}
	cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
			      v, CX18_AI1_MUX_MASK);

	/* Enable WW auto audio standard detection */
	v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
	v |= 0xFF;   /* Auto by default */
	v |= 0x400;  /* Stereo by default */
	v |= 0x14000000;
	cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);

	release_firmware(fw);
	return 0;
}
static int css2600_pci_probe(struct pci_dev *pdev,
			     const struct pci_device_id *id)
{
	struct css2600_device *isp;
	phys_addr_t phys;
	void __iomem *mmu_base[CSS2600_MMU_MAX_DEVICES];
	struct css2600_bus_iommu *isys_iommu, *psys_iommu;
	void __iomem * const *iomap;
	void __iomem *isys_base = NULL;
	void __iomem *psys_base = NULL;
	char *fw_binary;
	unsigned int iommus = 0;
	unsigned int dma_mask = 39;
	int rval;

	isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
	if (!isp) {
		dev_err(&pdev->dev, "Failed to alloc CI ISP structure\n");
		return -ENOMEM;
	}
	isp->pdev = pdev;
	INIT_LIST_HEAD(&isp->devices);

	isys_iommu = devm_kzalloc(&pdev->dev, sizeof(*isys_iommu), GFP_KERNEL);
	psys_iommu = devm_kzalloc(&pdev->dev, sizeof(*psys_iommu), GFP_KERNEL);
	if (!isys_iommu || !psys_iommu) {
		dev_err(&pdev->dev, "Can't allocate memory for iommu\n");
		return -ENOMEM;
	}

	/* Share IOMMU mapping between isys and psys */
	isys_iommu->m = psys_iommu->m = devm_kzalloc(
		&pdev->dev, sizeof(*isys_iommu->m), GFP_KERNEL);
	if (!isys_iommu->m) {
		dev_err(&pdev->dev,
			"Can't allocate memory for iommu mapping\n");
		return -ENOMEM;
	}

	rval = pcim_enable_device(pdev);
	if (rval) {
		dev_err(&pdev->dev, "Failed to enable CI ISP device (%d)\n",
			rval);
		return rval;
	}

	phys = pci_resource_start(pdev, CSS2600_PCI_BAR);

	rval = pcim_iomap_regions(pdev, 1 << CSS2600_PCI_BAR, pci_name(pdev));
	if (rval) {
		dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n",
			rval);
		return rval;
	}
	dev_info(&pdev->dev, "physical base address 0x%llx\n", phys);

	iomap = pcim_iomap_table(pdev);
	if (!iomap) {
		dev_err(&pdev->dev, "Failed to iomap table (%d)\n", rval);
		return -ENODEV;
	}

	isp->base = iomap[CSS2600_PCI_BAR];
	dev_info(&pdev->dev, "mapped as: 0x%p\n", isp->base);

	pci_set_drvdata(pdev, isp);

	pci_set_master(pdev);

	switch (isp->pdev->device) {
	case CSS2600_HW_MRFLD_2401:
		psys_base = isp->base;
		isys_base = isp->base;
		fw_binary = CSS2401_FIRMWARE;
		break;
	case CSS2600_HW_BXT_FPGA:
		dma_mask = 32;
		/* fall through */
	case CSS2600_HW_BXT:
		psys_base = isp->base + CSS2600_BXT_A0_PSYS_OFFSET;
		isys_base = isp->base + CSS2600_BXT_A0_ISYS_OFFSET;
		fw_binary = NULL;
		break;
	default:
		dev_err(&pdev->dev, "Not supported device\n");
		return -EINVAL;
	}

	rval = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_mask));
	if (!rval)
		rval = pci_set_consistent_dma_mask(pdev,
						   DMA_BIT_MASK(dma_mask));
	if (rval) {
		dev_err(&pdev->dev, "Failed to set DMA mask (%d)\n", rval);
		return rval;
	}

	if (fw_binary)
		rval = request_firmware(&isp->fw, fw_binary, &pdev->dev);
	if (rval) {
		dev_err(&pdev->dev, "Requesting firmware failed\n");
		return rval;
	}
	css2600_wrapper_init(psys_base, isys_base, isp->fw);

	if (pdev->device == CSS2600_HW_BXT) {
		isp->buttress = css2600_buttress_init(pdev, &pdev->dev, isp->base, 0);
		rval = PTR_ERR(isp->buttress);
		if (IS_ERR(isp->buttress))
			goto out_css2600_bus_del_devices;
	}
	if (pdev->device == CSS2600_HW_BXT
	    || (pdev->device == CSS2600_HW_BXT_FPGA
		&& IS_ENABLED(CONFIG_VIDEO_CSS2600_ISYS))) {
		mmu_base[0] = isys_base + CSS2600_BXT_A0_ISYS_IOMMU0_OFFSET;
		mmu_base[1] = isys_base + CSS2600_BXT_A0_ISYS_IOMMU1_OFFSET;
		isp->isys_iommu = css2600_mmu_init(pdev, &isp->buttress->dev,
			mmu_base, 2, 0, CSS2600_MMU_TYPE_CSS2600);
		rval = PTR_ERR(isp->isys_iommu);
		if (IS_ERR(isp->isys_iommu)) {
			dev_err(&pdev->dev, "can't create isys iommu device\n");
			return -ENOMEM;
		}

		rval = css2600_isys_iomem_filters_add(&pdev->dev, mmu_base, 2, 0xc);
		if (rval)
			goto out_css2600_bus_del_devices;
		iommus++;

		isys_iommu->dev = &isp->isys_iommu->dev;

		isp->isys = css2600_isys_init(
			pdev, &isp->buttress->dev, isys_iommu, isys_base,
			&isys_ipdata_2600, pdev->dev.platform_data, 0,
			pdev->device == CSS2600_HW_BXT ?
			CSS2600_ISYS_TYPE_CSS2600 :
			CSS2600_ISYS_TYPE_CSS2600_FPGA);
		rval = PTR_ERR(isp->isys);
		if (IS_ERR(isp->isys))
			goto out_css2600_bus_del_devices;
	}

	if (pdev->device == CSS2600_HW_BXT
	    || (pdev->device == CSS2600_HW_BXT_FPGA
		&& IS_ENABLED(CONFIG_VIDEO_CSS2600_PSYS))) {
		mmu_base[0] = psys_base + CSS2600_BXT_A0_PSYS_IOMMU0_OFFSET;
		mmu_base[1] = psys_base + CSS2600_BXT_A0_PSYS_IOMMU1_OFFSET;
		isp->psys_iommu = css2600_mmu_init(pdev, &isp->isys->dev,
			mmu_base, 2, 1, CSS2600_MMU_TYPE_CSS2600);
		rval = PTR_ERR(isp->psys_iommu);
		if (IS_ERR(isp->psys_iommu)) {
			dev_err(&pdev->dev, "can't create psys iommu device\n");
			goto out_css2600_bus_del_devices;
		}

		rval = css2600_isys_iomem_filters_add(&pdev->dev, mmu_base, 2, 0xc);
		if (rval)
			goto out_css2600_bus_del_devices;
		iommus++;

		psys_iommu->dev = &isp->psys_iommu->dev;
		isp->psys = css2600_psys_init(pdev, &isp->buttress->dev, psys_iommu, psys_base, 0);
		rval = PTR_ERR(isp->isys);
		if (IS_ERR(isp->isys))
			goto out_css2600_bus_del_devices;
	}

	if (pdev->device == CSS2600_HW_MRFLD_2401) {
		u32 val;

		mmu_base[0] = isp->base + CSS2600_MRFLD_DATA_IOMMU_OFFSET;
		mmu_base[1] = isp->base + CSS2600_MRFLD_ICACHE_IOMMU_OFFSET;
		isp->isys_iommu = css2600_mmu_init(pdev, &pdev->dev, mmu_base,
			2, 0, CSS2600_MMU_TYPE_CSS2401);
		rval = PTR_ERR(isp->isys_iommu);
		if (IS_ERR(isp->isys_iommu)) {
			dev_err(&pdev->dev, "can't create iommu device\n");
			goto out_css2600_bus_del_devices;
		}

		rval = css2600_isys_iomem_filters_add(&pdev->dev, mmu_base, 2, 0xc);
		if (rval)
			goto out_css2600_bus_del_devices;
		iommus++;

		isys_iommu->dev = &isp->isys_iommu->dev;
		isp->isys = css2600_isys_init(
			pdev, &pdev->dev, isys_iommu, isp->base,
			&isys_ipdata_2401, pdev->dev.platform_data, 0,
			CSS2600_ISYS_TYPE_CSS2401);
		rval = PTR_ERR(isp->isys);
		if (rval < 0)
			goto out_css2600_bus_del_devices;
		isp->psys = css2600_psys_init(pdev, &isp->isys->dev, isys_iommu,
					      isp->base, 0);
		rval = PTR_ERR(isp->psys);
		if (rval < 0)
			goto out_css2600_bus_del_devices;

		writel(CSS2401_CSI_RECEIVER_SELECTION_INTEL,
		       isp->base + CSS2401_REG_CSI_RECEIVER_SELECTION);

		/* Ensure read/write combining is enabled. */
		pci_read_config_dword(pdev, CSS2401_REG_PCI_I_CONTROL, &val);
		val |= CSS2401_PCI_I_CONTROL_ENABLE_READ_COMBINING |
			CSS2401_PCI_I_CONTROL_ENABLE_WRITE_COMBINING;
		pci_write_config_dword(pdev, CSS2401_REG_PCI_I_CONTROL, val);

		/*
		 * Hardware bugs require setting CSI_HS_OVR_CLK_GATE_ON_UPDATE.
		 * ANN/CHV: RCOMP updates do not happen when using CSI2+ path
		 * and sensor sending "continuous clock".
		 * TNG/ANN/CHV: MIPI packets are lost if the HS entry sequence
		 * is missed, and IUNIT can hang.
		 * For both issues, setting this bit is a workaround.
		 */
		pci_read_config_dword(pdev, CSS2401_REG_PCI_CSI_RCOMP_CONTROL,
				      &val);
		val |= CSS2401_PCI_CSI_HS_OVR_CLK_GATE_ON_UPDATE;
		pci_write_config_dword(pdev, CSS2401_REG_PCI_CSI_RCOMP_CONTROL,
				       val);

		pci_read_config_dword(pdev, CSS2401_REG_PCI_CSI_CONTROL, &val);
		val |= CSS2401_PCI_CSI_CONTROL_PARPATHEN;
		pci_write_config_dword(pdev, CSS2401_REG_PCI_CSI_CONTROL, val);
	}

	rval = css2600_pci_config_setup(pdev,
					pdev->device != CSS2600_HW_BXT_FPGA);
	if (rval)
		goto out_css2600_bus_del_devices;

	rval = css2600_wrapper_set_iommus(iommus);
	if (rval)
		goto out_css2600_bus_del_devices;

	rval = css2600_wrapper_set_device(&isp->isys->dev);
	if (rval)
		goto out_css2600_bus_del_devices;

	rval = devm_request_threaded_irq(&pdev->dev, pdev->irq,	css2600_isr,
					 css2600_isr_thread, IRQF_SHARED,
					 CSS2600_NAME, isp);
	if (rval) {
		dev_err(&pdev->dev, "Requesting threaded irq failed(%d)\n",
			rval);
		goto out_css2600_bus_del_devices;
	}

	pm_runtime_put_noidle(&pdev->dev);
	pm_runtime_allow(&pdev->dev);

	return 0;

out_css2600_bus_del_devices:
	css2600_isys_iomem_filter_remove(&pdev->dev);
	css2600_bus_del_devices(pdev);
	release_firmware(isp->fw);

	return rval;
}
Ejemplo n.º 9
0
static int load_segment(const struct elf32_phdr *phdr, unsigned num,
		struct pil_device *pil)
{
	int ret = 0, count, paddr;
	char fw_name[30];
	const struct firmware *fw = NULL;
	const u8 *data;

	if (memblock_overlaps_memory(phdr->p_paddr, phdr->p_memsz)) {
		dev_err(&pil->dev, "%s: kernel memory would be overwritten "
			"[%#08lx, %#08lx)\n", pil->desc->name,
			(unsigned long)phdr->p_paddr,
			(unsigned long)(phdr->p_paddr + phdr->p_memsz));
		return -EPERM;
	}

	if (phdr->p_filesz) {
		snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d",
				pil->desc->name, num);
		ret = request_firmware(&fw, fw_name, &pil->dev);
		if (ret) {
			dev_err(&pil->dev, "%s: Failed to locate blob %s\n",
					pil->desc->name, fw_name);
			return ret;
		}

		if (fw->size != phdr->p_filesz) {
			dev_err(&pil->dev, "%s: Blob size %u doesn't match "
					"%u\n", pil->desc->name, fw->size,
					phdr->p_filesz);
			ret = -EPERM;
			goto release_fw;
		}
	}

	/* Load the segment into memory */
	count = phdr->p_filesz;
	paddr = phdr->p_paddr;
	data = fw ? fw->data : NULL;
	while (count > 0) {
		int size;
		u8 __iomem *buf;

		size = min_t(size_t, IOMAP_SIZE, count);
		buf = ioremap(paddr, size);
		if (!buf) {
			dev_err(&pil->dev, "%s: Failed to map memory\n",
					pil->desc->name);
			ret = -ENOMEM;
			goto release_fw;
		}
		memcpy(buf, data, size);
		iounmap(buf);

		count -= size;
		paddr += size;
		data += size;
	}

	/* Zero out trailing memory */
	count = phdr->p_memsz - phdr->p_filesz;
	while (count > 0) {
		int size;
		u8 __iomem *buf;

		size = min_t(size_t, IOMAP_SIZE, count);
		buf = ioremap(paddr, size);
		if (!buf) {
			dev_err(&pil->dev, "%s: Failed to map memory\n",
					pil->desc->name);
			ret = -ENOMEM;
			goto release_fw;
		}
		memset(buf, 0, size);
		iounmap(buf);

		count -= size;
		paddr += size;
	}

	if (pil->desc->ops->verify_blob) {
		ret = pil->desc->ops->verify_blob(pil->desc, phdr->p_paddr,
					  phdr->p_memsz);
		if (ret)
			dev_err(&pil->dev, "%s: Blob%u failed verification\n",
				pil->desc->name, num);
	}

release_fw:
	release_firmware(fw);
	return ret;
}
Ejemplo n.º 10
0
static int
isl_upload_firmware(islpci_private *priv)
{
	u32 reg, rc;
	void __iomem *device_base = priv->device_base;

	/* clear the RAMBoot and the Reset bit */
	reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
	reg &= ~ISL38XX_CTRL_STAT_RESET;
	reg &= ~ISL38XX_CTRL_STAT_RAMBOOT;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	/* set the Reset bit without reading the register ! */
	reg |= ISL38XX_CTRL_STAT_RESET;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	/* clear the Reset bit */
	reg &= ~ISL38XX_CTRL_STAT_RESET;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();

	/* wait a while for the device to reboot */
	mdelay(50);

	{
		const struct firmware *fw_entry = NULL;
		long fw_len;
		const u32 *fw_ptr;

		rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
		if (rc)
			return rc;

		/* prepare the Direct Memory Base register */
		reg = ISL38XX_DEV_FIRMWARE_ADDRES;

		fw_ptr = (u32 *) fw_entry->data;
		fw_len = fw_entry->size;

		if (fw_len % 4) {
			printk(KERN_ERR
			       "%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
			       "prism54", priv->firmware);
			release_firmware(fw_entry);
			return -EILSEQ; /* Illegal byte sequence  */;
		}

		while (fw_len > 0) {
			long _fw_len =
			    (fw_len >
			     ISL38XX_MEMORY_WINDOW_SIZE) ?
			    ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
			u32 __iomem *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;

			/* set the card's base address for writing the data */
			isl38xx_w32_flush(device_base, reg,
					  ISL38XX_DIR_MEM_BASE_REG);
			wmb();	/* be paranoid */

			/* increment the write address for next iteration */
			reg += _fw_len;
			fw_len -= _fw_len;

			/* write the data to the Direct Memory Window 32bit-wise */
			/* memcpy_toio() doesn't guarantee 32bit writes :-| */
			while (_fw_len > 0) {
				/* use non-swapping writel() */
				__raw_writel(*fw_ptr, dev_fw_ptr);
				fw_ptr++, dev_fw_ptr++;
				_fw_len -= 4;
			}

			/* flush PCI posting */
			(void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH);
			wmb();	/* be paranoid again */

			BUG_ON(_fw_len != 0);
		}

		BUG_ON(fw_len != 0);

		/* Firmware version is at offset 40 (also for "newmac") */
		printk(KERN_DEBUG "%s: firmware version: %.8s\n",
		       priv->ndev->name, fw_entry->data + 40);

		release_firmware(fw_entry);
	}

	/* now reset the device
	 * clear the Reset & ClkRun bit, set the RAMBoot bit */
	reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
	reg &= ~ISL38XX_CTRL_STAT_CLKRUN;
	reg &= ~ISL38XX_CTRL_STAT_RESET;
	reg |= ISL38XX_CTRL_STAT_RAMBOOT;
	isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG);
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	/* set the reset bit latches the host override and RAMBoot bits
	 * into the device for operation when the reset bit is reset */
	reg |= ISL38XX_CTRL_STAT_RESET;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	/* don't do flush PCI posting here! */
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	/* clear the reset bit should start the whole circus */
	reg &= ~ISL38XX_CTRL_STAT_RESET;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	/* don't do flush PCI posting here! */
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	return 0;
}
Ejemplo n.º 11
0
static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
				      const struct i2c_device_id *i2c_id)
{
	struct wm2000_priv *wm2000;
	struct wm2000_platform_data *pdata;
	const char *filename;
	const struct firmware *fw;
	int reg, ret;
	u16 id;

	wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv),
			      GFP_KERNEL);
	if (wm2000 == NULL) {
		dev_err(&i2c->dev, "Unable to allocate private data\n");
		return -ENOMEM;
	}

	dev_set_drvdata(&i2c->dev, wm2000);

	wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap);
	if (IS_ERR(wm2000->regmap)) {
		ret = PTR_ERR(wm2000->regmap);
		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
			ret);
		goto err;
	}

	/* Verify that this is a WM2000 */
	reg = wm2000_read(i2c, WM2000_REG_ID1);
	id = reg << 8;
	reg = wm2000_read(i2c, WM2000_REG_ID2);
	id |= reg & 0xff;

	if (id != 0x2000) {
		dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
		ret = -ENODEV;
		goto err_regmap;
	}

	reg = wm2000_read(i2c, WM2000_REG_REVISON);
	dev_info(&i2c->dev, "revision %c\n", reg + 'A');

	filename = "wm2000_anc.bin";
	pdata = dev_get_platdata(&i2c->dev);
	if (pdata) {
		wm2000->mclk_div = pdata->mclkdiv2;
		wm2000->speech_clarity = !pdata->speech_enh_disable;

		if (pdata->download_file)
			filename = pdata->download_file;
	}

	ret = request_firmware(&fw, filename, &i2c->dev);
	if (ret != 0) {
		dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
		goto err_regmap;
	}

	/* Pre-cook the concatenation of the register address onto the image */
	wm2000->anc_download_size = fw->size + 2;
	wm2000->anc_download = devm_kzalloc(&i2c->dev,
					    wm2000->anc_download_size,
					    GFP_KERNEL);
	if (wm2000->anc_download == NULL) {
		dev_err(&i2c->dev, "Out of memory\n");
		ret = -ENOMEM;
		goto err_fw;
	}

	wm2000->anc_download[0] = 0x80;
	wm2000->anc_download[1] = 0x00;
	memcpy(wm2000->anc_download + 2, fw->data, fw->size);

	release_firmware(fw);

	wm2000->anc_eng_ena = 1;
	wm2000->anc_active = 1;
	wm2000->spk_ena = 1;
	wm2000->i2c = i2c;

	wm2000_reset(wm2000);

	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000,
				     NULL, 0);
	if (ret != 0)
		goto err_fw;

	return 0;

err_fw:
	release_firmware(fw);
err_regmap:
	regmap_exit(wm2000->regmap);
err:
	return ret;
}
Ejemplo n.º 12
0
Archivo: ni.c Proyecto: SimonPe/linux
int ni_init_microcode(struct radeon_device *rdev)
{
	struct platform_device *pdev;
	const char *chip_name;
	const char *rlc_chip_name;
	size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
	char fw_name[30];
	int err;

	DRM_DEBUG("\n");

	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
	err = IS_ERR(pdev);
	if (err) {
		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
		return -EINVAL;
	}

	switch (rdev->family) {
	case CHIP_BARTS:
		chip_name = "BARTS";
		rlc_chip_name = "BTC";
		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
		mc_req_size = BTC_MC_UCODE_SIZE * 4;
		break;
	case CHIP_TURKS:
		chip_name = "TURKS";
		rlc_chip_name = "BTC";
		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
		mc_req_size = BTC_MC_UCODE_SIZE * 4;
		break;
	case CHIP_CAICOS:
		chip_name = "CAICOS";
		rlc_chip_name = "BTC";
		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
		mc_req_size = BTC_MC_UCODE_SIZE * 4;
		break;
	case CHIP_CAYMAN:
		chip_name = "CAYMAN";
		rlc_chip_name = "CAYMAN";
		pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
		me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
		rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
		mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
		break;
	case CHIP_ARUBA:
		chip_name = "ARUBA";
		rlc_chip_name = "ARUBA";
		/* pfp/me same size as CAYMAN */
		pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
		me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
		rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
		mc_req_size = 0;
		break;
	default: BUG();
	}

	DRM_INFO("Loading %s Microcode\n", chip_name);

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
	err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
	if (err)
		goto out;
	if (rdev->pfp_fw->size != pfp_req_size) {
		printk(KERN_ERR
		       "ni_cp: Bogus length %zu in firmware \"%s\"\n",
		       rdev->pfp_fw->size, fw_name);
		err = -EINVAL;
		goto out;
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
	err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
	if (err)
		goto out;
	if (rdev->me_fw->size != me_req_size) {
		printk(KERN_ERR
		       "ni_cp: Bogus length %zu in firmware \"%s\"\n",
		       rdev->me_fw->size, fw_name);
		err = -EINVAL;
	}

	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
	err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
	if (err)
		goto out;
	if (rdev->rlc_fw->size != rlc_req_size) {
		printk(KERN_ERR
		       "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
		       rdev->rlc_fw->size, fw_name);
		err = -EINVAL;
	}

	/* no MC ucode on TN */
	if (!(rdev->flags & RADEON_IS_IGP)) {
		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
		err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
		if (err)
			goto out;
		if (rdev->mc_fw->size != mc_req_size) {
			printk(KERN_ERR
			       "ni_mc: Bogus length %zu in firmware \"%s\"\n",
			       rdev->mc_fw->size, fw_name);
			err = -EINVAL;
		}
	}
out:
	platform_device_unregister(pdev);

	if (err) {
		if (err != -EINVAL)
			printk(KERN_ERR
			       "ni_cp: Failed to load firmware \"%s\"\n",
			       fw_name);
		release_firmware(rdev->pfp_fw);
		rdev->pfp_fw = NULL;
		release_firmware(rdev->me_fw);
		rdev->me_fw = NULL;
		release_firmware(rdev->rlc_fw);
		rdev->rlc_fw = NULL;
		release_firmware(rdev->mc_fw);
		rdev->mc_fw = NULL;
	}
	return err;
}
bool FirmwareDownload92S(struct net_device *dev)
{	
	struct r8192_priv 	*priv = rtllib_priv(dev);
	bool			rtStatus = true;
	u8			*pucMappedFile = NULL;
	u32			ulFileLength = 0;	
	u8			FwHdrSize = RT_8192S_FIRMWARE_HDR_SIZE;	
	rt_firmware		*pFirmware = priv->pFirmware;
	u8			FwStatus = FW_STATUS_INIT;
	PRT_8192S_FIRMWARE_HDR	pFwHdr = NULL;
	PRT_8192S_FIRMWARE_PRIV	pFwPriv = NULL;
	
	pFirmware->FWStatus = FW_STATUS_INIT;

	RT_TRACE(COMP_FIRMWARE, " --->FirmwareDownload92S()\n");

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) && defined(USE_FW_SOURCE_IMG_FILE)
	priv->firmware_source = FW_SOURCE_IMG_FILE;
#else
	priv->firmware_source = FW_SOURCE_HEADER_FILE;
#endif

	switch( priv->firmware_source )
	{
		case FW_SOURCE_IMG_FILE:		
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) && defined(USE_FW_SOURCE_IMG_FILE)			
			if(pFirmware->szFwTmpBufferLen == 0)
			{
#ifdef _RTL8192_EXT_PATCH_
				const char 		*pFwImageFileName[1] = {"RTL8191SE_MESH/rtl8192sfw.bin"};
#else
				const char 		*pFwImageFileName[1] = {"RTL8192SE/rtl8192sfw.bin"};
#endif
				const struct firmware 	*fw_entry = NULL;
				u32 ulInitStep = 0;
				int 			rc = 0;
				u32			file_length = 0;
				rc = request_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->pdev->dev);
				if(rc < 0 ) {
					RT_TRACE(COMP_ERR, "request firmware fail!\n");
					goto DownloadFirmware_Fail;
				} 

				if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) {
					RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
					release_firmware(fw_entry);
					goto DownloadFirmware_Fail;
				}

				memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size);
				pFirmware->szFwTmpBufferLen = fw_entry->size;
				release_firmware(fw_entry);

				pucMappedFile = pFirmware->szFwTmpBuffer;
				file_length = pFirmware->szFwTmpBufferLen;

				pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;				
				pFwHdr = pFirmware->pFwHeader;
				RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \
						pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \
						pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE);
				pFirmware->FirmwareVersion =  byte(pFwHdr->Version ,0);			
				if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM)))
				{
					RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\
							__FUNCTION__);
					goto DownloadFirmware_Fail;
				} else {				
					pucMappedFile+=FwHdrSize;

					memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
					pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;				
				}

				if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM))
				{
					RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\
							__FUNCTION__);	
					goto DownloadFirmware_Fail;
				}
				else
				{	
					pucMappedFile += pFirmware->FwIMEMLen;

					memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);
					pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;		
				}	
			}
#endif
			break;	

		case FW_SOURCE_HEADER_FILE:	
#if 1
#define Rtl819XFwImageArray Rtl8192SEFwImgArray
			pucMappedFile = Rtl819XFwImageArray;
			ulFileLength = ImgArrayLength;

			RT_TRACE(COMP_INIT,"Fw download from header.\n");
			pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;				
			pFwHdr = pFirmware->pFwHeader;
			RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \
					pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \
					pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE);
			pFirmware->FirmwareVersion =  byte(pFwHdr->Version ,0);			

			if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM)))
			{
				printk("FirmwareDownload92S(): memory for data image is less than IMEM required\n");					
				goto DownloadFirmware_Fail;
			}
			else
			{				
				pucMappedFile+=FwHdrSize;

				memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
				pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;				
			}

			if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM))
			{
				printk(" FirmwareDownload92S(): memory for data image is less than EMEM required\n");					
				goto DownloadFirmware_Fail;
			} else {	
				pucMappedFile+= pFirmware->FwIMEMLen;

				memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);
				pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;		
			}
#endif
			break;
		default:
			break;
	}			

	FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
	while(FwStatus!= FW_STATUS_READY)
	{
		switch(FwStatus)
		{
			case FW_STATUS_LOAD_IMEM:				
				pucMappedFile = pFirmware->FwIMEM;
				ulFileLength = pFirmware->FwIMEMLen;					
				break;

			case FW_STATUS_LOAD_EMEM:				
				pucMappedFile = pFirmware->FwEMEM;
				ulFileLength = pFirmware->FwEMEMLen;					
				break;

			case FW_STATUS_LOAD_DMEM:			
				pFwHdr = pFirmware->pFwHeader;
				pFwPriv = (PRT_8192S_FIRMWARE_PRIV)&pFwHdr->FWPriv;
				FirmwareHeaderPriveUpdate(dev, pFwPriv);
				pucMappedFile = (u8*)(pFirmware->pFwHeader)+RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
				ulFileLength = FwHdrSize-RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;				
				break;
					
			default:
				RT_TRACE(COMP_ERR, "Unexpected Download step!!\n");
				goto DownloadFirmware_Fail;
				break;
		}		
		
		rtStatus = FirmwareDownloadCode(dev, pucMappedFile, ulFileLength);	
		
		if(rtStatus != true)
		{
			RT_TRACE(COMP_ERR, "FirmwareDownloadCode() fail ! \n" );
			goto DownloadFirmware_Fail;
		}	
		
		rtStatus = FirmwareCheckReady(dev, FwStatus);

		if(rtStatus != true)
		{
			RT_TRACE(COMP_ERR, "FirmwareDownloadCode() fail ! \n");
			goto DownloadFirmware_Fail;
		}
		
		FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
	}

	RT_TRACE(COMP_FIRMWARE, "Firmware Download Success!!\n");	
	return rtStatus;	
	
	DownloadFirmware_Fail:	
	RT_TRACE(COMP_ERR, "Firmware Download Fail!!%x\n",read_nic_word(dev, TCR));	
	rtStatus = false;
	return rtStatus;	
}
Ejemplo n.º 14
0
int radeon_uvd_init(struct radeon_device *rdev)
{
    unsigned long bo_size;
    const char *fw_name;
    int i, r;

    INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);

    switch (rdev->family) {
    case CHIP_RV710:
    case CHIP_RV730:
    case CHIP_RV740:
        fw_name = FIRMWARE_RV710;
        break;

    case CHIP_CYPRESS:
    case CHIP_HEMLOCK:
    case CHIP_JUNIPER:
    case CHIP_REDWOOD:
    case CHIP_CEDAR:
        fw_name = FIRMWARE_CYPRESS;
        break;

    case CHIP_SUMO:
    case CHIP_SUMO2:
    case CHIP_PALM:
    case CHIP_CAYMAN:
    case CHIP_BARTS:
    case CHIP_TURKS:
    case CHIP_CAICOS:
        fw_name = FIRMWARE_SUMO;
        break;

    case CHIP_TAHITI:
    case CHIP_VERDE:
    case CHIP_PITCAIRN:
    case CHIP_ARUBA:
        fw_name = FIRMWARE_TAHITI;
        break;

    case CHIP_BONAIRE:
    case CHIP_KABINI:
    case CHIP_KAVERI:
        fw_name = FIRMWARE_BONAIRE;
        break;

    default:
        return -EINVAL;
    }

    r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev);
    if (r) {
        dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
                fw_name);
        return r;
    }

    bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
              RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
    r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
                         RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo);
    if (r) {
        dev_err(rdev->dev, "(%d) failed to allocate UVD bo\n", r);
        return r;
    }

    r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
    if (r) {
        radeon_bo_unref(&rdev->uvd.vcpu_bo);
        dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r);
        return r;
    }

    r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM,
                      &rdev->uvd.gpu_addr);
    if (r) {
        radeon_bo_unreserve(rdev->uvd.vcpu_bo);
        radeon_bo_unref(&rdev->uvd.vcpu_bo);
        dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r);
        return r;
    }

    r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr);
    if (r) {
        dev_err(rdev->dev, "(%d) UVD map failed\n", r);
        return r;
    }

    radeon_bo_unreserve(rdev->uvd.vcpu_bo);

    for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
        atomic_set(&rdev->uvd.handles[i], 0);
        rdev->uvd.filp[i] = NULL;
        rdev->uvd.img_size[i] = 0;
    }

    return 0;
}
Ejemplo n.º 15
0
/*
 * predef should be 0 for loading user defined mcs
 * predef should be YAM_1200 for loading predef 1200 mcs
 * predef should be YAM_9600 for loading predef 9600 mcs
 */
static unsigned char *add_mcs(unsigned char *bits, int bitrate,
			      unsigned int predef)
{
	const char *fw_name[2] = {FIRMWARE_9600, FIRMWARE_1200};
	const struct firmware *fw;
	struct platform_device *pdev;
	struct yam_mcs *p;
	int err;

	switch (predef) {
	case 0:
		fw = NULL;
		break;
	case YAM_1200:
	case YAM_9600:
		predef--;
		pdev = platform_device_register_simple("yam", 0, NULL, 0);
		if (IS_ERR(pdev)) {
			printk(KERN_ERR "yam: Failed to register firmware\n");
			return NULL;
		}
		err = request_firmware(&fw, fw_name[predef], &pdev->dev);
		platform_device_unregister(pdev);
		if (err)
			return NULL;
		if (fw->size != YAM_FPGA_SIZE) {
			printk(KERN_ERR "Bogus length %zu in firmware \"%s\"\n",
			       fw->size, fw_name[predef]);
			release_firmware(fw);
			return NULL;
		}
		bits = (unsigned char *)fw->data;
		break;
	default:
		printk(KERN_ERR "yam: Invalid predef number %u\n", predef);
		return NULL;
	}

	/* If it already exists, replace the bit data */
	p = yam_data;
	while (p) {
		if (p->bitrate == bitrate) {
			memcpy(p->bits, bits, YAM_FPGA_SIZE);
			goto out;
		}
		p = p->next;
	}

	/* Allocate a new mcs */
	if ((p = kmalloc(sizeof(struct yam_mcs), GFP_KERNEL)) == NULL) {
		release_firmware(fw);
		return NULL;
	}
	memcpy(p->bits, bits, YAM_FPGA_SIZE);
	p->bitrate = bitrate;
	p->next = yam_data;
	yam_data = p;
 out:
	release_firmware(fw);
	return p->bits;
}
Ejemplo n.º 16
0
static int load_image(struct pil_device *pil)
{
	int i, ret;
	char fw_name[30];
	struct elf32_hdr *ehdr;
	const struct elf32_phdr *phdr;
	const struct firmware *fw;
	unsigned long proxy_timeout = pil->desc->proxy_timeout;

	down_read(&pil_pm_rwsem);
	snprintf(fw_name, sizeof(fw_name), "%s.mdt", pil->desc->name);
	ret = request_firmware(&fw, fw_name, &pil->dev);
	if (ret) {
		dev_err(&pil->dev, "%s: Failed to locate %s\n",
				pil->desc->name, fw_name);
		goto out;
	}

	if (fw->size < sizeof(*ehdr)) {
		dev_err(&pil->dev, "%s: Not big enough to be an elf header\n",
				pil->desc->name);
		ret = -EIO;
		goto release_fw;
	}

	ehdr = (struct elf32_hdr *)fw->data;
	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
		dev_err(&pil->dev, "%s: Not an elf header\n", pil->desc->name);
		ret = -EIO;
		goto release_fw;
	}

	if (ehdr->e_phnum == 0) {
		dev_err(&pil->dev, "%s: No loadable segments\n",
				pil->desc->name);
		ret = -EIO;
		goto release_fw;
	}
	if (sizeof(struct elf32_phdr) * ehdr->e_phnum +
	    sizeof(struct elf32_hdr) > fw->size) {
		dev_err(&pil->dev, "%s: Program headers not within mdt\n",
				pil->desc->name);
		ret = -EIO;
		goto release_fw;
	}

	ret = pil->desc->ops->init_image(pil->desc, fw->data, fw->size);
	if (ret) {
		dev_err(&pil->dev, "%s: Invalid firmware metadata\n",
				pil->desc->name);
		goto release_fw;
	}

	phdr = (const struct elf32_phdr *)(fw->data + sizeof(struct elf32_hdr));
	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
		if (!segment_is_loadable(phdr))
			continue;

		ret = load_segment(phdr, i, pil);
		if (ret) {
			dev_err(&pil->dev, "%s: Failed to load segment %d\n",
					pil->desc->name, i);
			goto release_fw;
		}
	}

	ret = pil_proxy_vote(pil);
	if (ret) {
		dev_err(&pil->dev, "%s: Failed to proxy vote\n",
					pil->desc->name);
		goto release_fw;
	}

	ret = pil->desc->ops->auth_and_reset(pil->desc);
	if (ret) {
		dev_err(&pil->dev, "%s: Failed to bring out of reset\n",
				pil->desc->name);
		proxy_timeout = 0; /* Remove proxy vote immediately on error */
		goto err_boot;
	}
	dev_info(&pil->dev, "%s: Brought out of reset\n", pil->desc->name);
err_boot:
	pil_proxy_unvote(pil, proxy_timeout);
release_fw:
	release_firmware(fw);
out:
	up_read(&pil_pm_rwsem);
	return ret;
}
Ejemplo n.º 17
0
static int zd1201_fw_upload(struct usb_device *dev, int apfw)
{
	const struct firmware *fw_entry;
	const char *data;
	unsigned long len;
	int err;
	unsigned char ret;
	char *buf;
	char *fwfile;

	if (apfw)
		fwfile = "zd1201-ap.fw";
	else
		fwfile = "zd1201.fw";

	err = request_firmware(&fw_entry, fwfile, &dev->dev);
	if (err) {
		dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile);
		dev_err(&dev->dev, "Make sure the hotplug firmware loader is installed.\n");
		dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n");
		return err;
	}

	data = fw_entry->data;
        len = fw_entry->size;

	buf = kmalloc(1024, GFP_ATOMIC);
	if (!buf)
		goto exit;

	while (len > 0) {
		int translen = (len > 1024) ? 1024 : len;
		memcpy(buf, data, translen);

		err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0,
		    USB_DIR_OUT | 0x40, 0, 0, buf, translen,
		    ZD1201_FW_TIMEOUT);
		if (err < 0)
			goto exit;

		len -= translen;
		data += translen;
	}

	err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x2,
	    USB_DIR_OUT | 0x40, 0, 0, NULL, 0, ZD1201_FW_TIMEOUT);
	if (err < 0)
		goto exit;

	err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4,
	    USB_DIR_IN | 0x40, 0, 0, buf, sizeof(ret), ZD1201_FW_TIMEOUT);
	if (err < 0)
		goto exit;

	memcpy(&ret, buf, sizeof(ret));

	if (ret & 0x80) {
		err = -EIO;
		goto exit;
	}

	err = 0;
exit:
	kfree(buf);
	release_firmware(fw_entry);
	return err;
}
Ejemplo n.º 18
0
static int __devinit myri_load_lanai(struct myri_eth *mp)
{
	const struct firmware	*fw;
	struct net_device	*dev = mp->dev;
	struct myri_shmem __iomem *shmem = mp->shmem;
	void __iomem		*rptr;
	int 			i, lanai4_data_size;

	myri_disable_irq(mp->lregs, mp->cregs);
	myri_reset_on(mp->cregs);

	rptr = mp->lanai;
	for (i = 0; i < mp->eeprom.ramsz; i++)
		sbus_writeb(0, rptr + i);

	if (mp->eeprom.cpuvers >= CPUVERS_3_0)
		sbus_writel(mp->eeprom.cval, mp->lregs + LANAI_CVAL);

	i = request_firmware(&fw, FWNAME, &mp->myri_op->dev);
	if (i) {
		printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
		       FWNAME, i);
		return i;
	}
	if (fw->size < 2) {
		printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
		       fw->size, FWNAME);
		release_firmware(fw);
		return -EINVAL;
	}
	lanai4_data_size = fw->data[0] << 8 | fw->data[1];

	
	for (i = 2; i < fw->size; i++)
		sbus_writeb(fw->data[i], rptr++);

	
	for (i = 0; i < lanai4_data_size; i++)
		sbus_writeb(0, rptr++);

	
	sbus_writeb(0, &shmem->addr[0]);
	sbus_writeb(0, &shmem->addr[1]);
	for (i = 0; i < 6; i++)
		sbus_writeb(dev->dev_addr[i],
			    &shmem->addr[i + 2]);

	
	sbus_writel(((mp->myri_bursts & 0xf8) >> 3), &shmem->burst);
	sbus_writel(SHMEM_IMASK_RX, &shmem->imask);

	
	myri_disable_irq(mp->lregs, mp->cregs);
	myri_reset_off(mp->lregs, mp->cregs);
	myri_disable_irq(mp->lregs, mp->cregs);

	
	for (i = 0; i < 5000; i++) {
		if (sbus_readl(&shmem->channel.state) != STATE_READY)
			break;
		else
			udelay(10);
	}

	if (i == 5000)
		printk(KERN_ERR "myricom: Chip would not reset after firmware load.\n");

	i = myri_do_handshake(mp);
	if (i)
		printk(KERN_ERR "myricom: Handshake with LANAI failed.\n");

	if (mp->eeprom.cpuvers == CPUVERS_4_0)
		sbus_writel(0, mp->lregs + LANAI_VERS);

	release_firmware(fw);
	return i;
}
Ejemplo n.º 19
0
/**
 *  lbs_get_firmware - Retrieves two-stage firmware
 *
 *  @dev:     	A pointer to &device structure
 *  @user_helper: User-defined helper firmware file
 *  @user_mainfw: User-defined main firmware file
 *  @card_model: Bus-specific card model ID used to filter firmware table
 *		elements
 *  @fw_table:	Table of firmware file names and device model numbers
 *		terminated by an entry with a NULL helper name
 *  @helper:	On success, the helper firmware; caller must free
 *  @mainfw:	On success, the main firmware; caller must free
 *
 *  returns:		0 on success, non-zero on failure
 */
int lbs_get_firmware(struct device *dev, const char *user_helper,
			const char *user_mainfw, u32 card_model,
			const struct lbs_fw_table *fw_table,
			const struct firmware **helper,
			const struct firmware **mainfw)
{
	const struct lbs_fw_table *iter;
	int ret;

	BUG_ON(helper == NULL);
	BUG_ON(mainfw == NULL);

	/* Try user-specified firmware first */
	if (user_helper) {
		ret = request_firmware(helper, user_helper, dev);
		if (ret) {
			dev_err(dev, "couldn't find helper firmware %s\n",
				user_helper);
			goto fail;
		}
	}
	if (user_mainfw) {
		ret = request_firmware(mainfw, user_mainfw, dev);
		if (ret) {
			dev_err(dev, "couldn't find main firmware %s\n",
				user_mainfw);
			goto fail;
		}
	}

	if (*helper && *mainfw)
		return 0;

	/* Otherwise search for firmware to use.  If neither the helper or
	 * the main firmware were specified by the user, then we need to
	 * make sure that found helper & main are from the same entry in
	 * fw_table.
	 */
	iter = fw_table;
	while (iter && iter->helper) {
		if (iter->model != card_model)
			goto next;

		if (*helper == NULL) {
			ret = request_firmware(helper, iter->helper, dev);
			if (ret)
				goto next;

			/* If the device has one-stage firmware (ie cf8305) and
			 * we've got it then we don't need to bother with the
			 * main firmware.
			 */
			if (iter->fwname == NULL)
				return 0;
		}

		if (*mainfw == NULL) {
			ret = request_firmware(mainfw, iter->fwname, dev);
			if (ret && !user_helper) {
				/* Clear the helper if it wasn't user-specified
				 * and the main firmware load failed, to ensure
				 * we don't have mismatched firmware pairs.
				 */
				release_firmware(*helper);
				*helper = NULL;
			}
		}

		if (*helper && *mainfw)
			return 0;

  next:
		iter++;
	}

  fail:
	/* Failed */
	if (*helper) {
		release_firmware(*helper);
		*helper = NULL;
	}
	if (*mainfw) {
		release_firmware(*mainfw);
		*mainfw = NULL;
	}

	return -ENOENT;
}
Ejemplo n.º 20
0
static void wcnss_nvbin_dnld(void)
{
	int ret = 0;
	struct nvbin_dnld_req_msg *dnld_req_msg;
	unsigned short total_fragments = 0;
	unsigned short count = 0;
	unsigned short retry_count = 0;
	unsigned short cur_frag_size = 0;
	unsigned char *outbuffer = NULL;
	const void *nv_blob_addr = NULL;
	unsigned int nv_blob_size = 0;
	const struct firmware *nv = NULL;
	struct device *dev = &penv->pdev->dev;

	ret = request_firmware(&nv, NVBIN_FILE, dev);

	if (ret || !nv || !nv->data || !nv->size) {
		pr_err("wcnss: %s: request_firmware failed for %s\n",
			__func__, NVBIN_FILE);
		return;
	}

	/*
	 * First 4 bytes in nv blob is validity bitmap.
	 * We cannot validate nv, so skip those 4 bytes.
	 */
	nv_blob_addr = nv->data + 4;
	nv_blob_size = nv->size - 4;

	total_fragments = TOTALFRAGMENTS(nv_blob_size);

	pr_info("wcnss: NV bin size: %d, total_fragments: %d\n",
		nv_blob_size, total_fragments);

	/* get buffer for nv bin dnld req message */
	outbuffer = kmalloc((sizeof(struct nvbin_dnld_req_msg) +
		NV_FRAGMENT_SIZE), GFP_KERNEL);

	if (NULL == outbuffer) {
		pr_err("wcnss: %s: failed to get buffer\n", __func__);
		goto err_free_nv;
	}

	dnld_req_msg = (struct nvbin_dnld_req_msg *)outbuffer;

	dnld_req_msg->hdr.msg_type = WCNSS_NVBIN_DNLD_REQ;
	dnld_req_msg->dnld_req_params.msg_flags = 0;

	for (count = 0; count < total_fragments; count++) {
		dnld_req_msg->dnld_req_params.frag_number = count;

		if (count == (total_fragments - 1)) {
			/* last fragment, take care of boundry condition */
			cur_frag_size = nv_blob_size % NV_FRAGMENT_SIZE;
			if (!cur_frag_size)
				cur_frag_size = NV_FRAGMENT_SIZE;

			dnld_req_msg->dnld_req_params.msg_flags |=
				LAST_FRAGMENT;
			dnld_req_msg->dnld_req_params.msg_flags |=
				CAN_RECEIVE_CALDATA;
		} else {
			cur_frag_size = NV_FRAGMENT_SIZE;
			dnld_req_msg->dnld_req_params.msg_flags &=
				~LAST_FRAGMENT;
		}

		dnld_req_msg->dnld_req_params.nvbin_buffer_size =
			cur_frag_size;

		dnld_req_msg->hdr.msg_len =
			sizeof(struct nvbin_dnld_req_msg) + cur_frag_size;

		/* copy NV fragment */
		memcpy((outbuffer + sizeof(struct nvbin_dnld_req_msg)),
			(nv_blob_addr + count * NV_FRAGMENT_SIZE),
			cur_frag_size);

		ret = wcnss_smd_tx(outbuffer, dnld_req_msg->hdr.msg_len);

		retry_count = 0;
		while ((ret == -ENOSPC) && (retry_count <= 3)) {
			pr_debug("wcnss: %s: smd tx failed, ENOSPC\n",
				__func__);
			pr_debug("fragment: %d, len: %d, TotFragments: %d, retry_count: %d\n",
				count, dnld_req_msg->hdr.msg_len,
				total_fragments, retry_count);

			/* wait and try again */
			msleep(20);
			retry_count++;
			ret = wcnss_smd_tx(outbuffer,
					dnld_req_msg->hdr.msg_len);
		}

		if (ret < 0) {
			pr_err("wcnss: %s: smd tx failed\n", __func__);
			pr_err("fragment %d, len: %d, TotFragments: %d, retry_count: %d\n",
				count, dnld_req_msg->hdr.msg_len,
				total_fragments, retry_count);
			goto err_dnld;
		}
	}

err_dnld:
	/* free buffer */
	kfree(outbuffer);

err_free_nv:
	/* release firmware */
	release_firmware(nv);

	return;
}
Ejemplo n.º 21
0
static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	const struct firmware *firmware;
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_host_endpoint *bulk_out_ep;
	struct usb_host_endpoint *bulk_in_ep;
	struct hci_dev *hdev;
	struct bfusb_data *data;

	BT_DBG("intf %p id %p", intf, id);

	/* Check number of endpoints */
	if (intf->cur_altsetting->desc.bNumEndpoints < 2)
		return -EIO;

	bulk_out_ep = &intf->cur_altsetting->endpoint[0];
	bulk_in_ep  = &intf->cur_altsetting->endpoint[1];

	if (!bulk_out_ep || !bulk_in_ep) {
		BT_ERR("Bulk endpoints not found");
		goto done;
	}

	/* Initialize control structure and load firmware */
	data = devm_kzalloc(&intf->dev, sizeof(struct bfusb_data), GFP_KERNEL);
	if (!data) {
		BT_ERR("Can't allocate memory for control structure");
		goto done;
	}

	data->udev = udev;
	data->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
	data->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
	data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);

	rwlock_init(&data->lock);

	data->reassembly = NULL;

	skb_queue_head_init(&data->transmit_q);
	skb_queue_head_init(&data->pending_q);
	skb_queue_head_init(&data->completed_q);

	if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
		BT_ERR("Firmware request failed");
		goto done;
	}

	BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);

	if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) {
		BT_ERR("Firmware loading failed");
		goto release;
	}

	release_firmware(firmware);

	/* Initialize and register HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		goto done;
	}

	data->hdev = hdev;

	hdev->bus = HCI_USB;
	hci_set_drvdata(hdev, data);
	SET_HCIDEV_DEV(hdev, &intf->dev);

	hdev->open  = bfusb_open;
	hdev->close = bfusb_close;
	hdev->flush = bfusb_flush;
	hdev->send  = bfusb_send_frame;

	set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks);

	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		goto done;
	}

	usb_set_intfdata(intf, data);

	return 0;

release:
	release_firmware(firmware);

done:
	return -EIO;
}
Ejemplo n.º 22
0
static int lme_firmware_switch(struct usb_device *udev, int cold)
{
	const struct firmware *fw = NULL;
	const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
	const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw";
	const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw";
	const char fw_lg[] = "dvb-usb-lme2510-lg.fw";
	const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw";
	const char *fw_lme;
	int ret, cold_fw;

	cold = (cold > 0) ? (cold & 1) : 0;

	cold_fw = !cold;

	if (le16_to_cpu(udev->descriptor.idProduct) == 0x1122) {
		switch (dvb_usb_lme2510_firmware) {
		default:
			dvb_usb_lme2510_firmware = TUNER_S0194;
		case TUNER_S0194:
			fw_lme = fw_s0194;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0) {
				cold = 0;
				break;
			}
			dvb_usb_lme2510_firmware = TUNER_LG;
		case TUNER_LG:
			fw_lme = fw_lg;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0)
				break;
			info("FRM No Firmware Found - please install");
			dvb_usb_lme2510_firmware = TUNER_DEFAULT;
			cold = 0;
			cold_fw = 0;
			break;
		}
	} else {
		switch (dvb_usb_lme2510_firmware) {
		default:
			dvb_usb_lme2510_firmware = TUNER_S7395;
		case TUNER_S7395:
			fw_lme = fw_c_s7395;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0) {
				cold = 0;
				break;
			}
			dvb_usb_lme2510_firmware = TUNER_LG;
		case TUNER_LG:
			fw_lme = fw_c_lg;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0)
				break;
			dvb_usb_lme2510_firmware = TUNER_S0194;
		case TUNER_S0194:
			fw_lme = fw_c_s0194;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0)
				break;
			info("FRM No Firmware Found - please install");
			dvb_usb_lme2510_firmware = TUNER_DEFAULT;
			cold = 0;
			cold_fw = 0;
			break;
		}
	}

	if (cold_fw) {
		info("FRM Loading %s file", fw_lme);
		ret = lme2510_download_firmware(udev, fw);
	}

	release_firmware(fw);

	if (cold) {
		info("FRM Changing to %s firmware", fw_lme);
		lme_coldreset(udev);
		return -ENODEV;
	}

	return ret;
}
Ejemplo n.º 23
0
static ssize_t asd_store_update_bios(struct device *dev,
	struct device_attribute *attr,
	const char *buf, size_t count)
{
	struct asd_ha_struct *asd_ha = dev_to_asd_ha(dev);
	char *cmd_ptr, *filename_ptr;
	struct bios_file_header header, *hdr_ptr;
	int res, i;
	u32 csum = 0;
	int flash_command = FLASH_CMD_NONE;
	int err = 0;

	cmd_ptr = kzalloc(count*2, GFP_KERNEL);

	if (!cmd_ptr) {
		err = FAIL_OUT_MEMORY;
		goto out;
	}

	filename_ptr = cmd_ptr + count;
	res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr);
	if (res != 2) {
		err = FAIL_PARAMETERS;
		goto out1;
	}

	for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) {
		if (!memcmp(flash_command_table[i].command,
				 cmd_ptr, strlen(cmd_ptr))) {
			flash_command = flash_command_table[i].code;
			break;
		}
	}
	if (flash_command == FLASH_CMD_NONE) {
		err = FAIL_PARAMETERS;
		goto out1;
	}

	if (asd_ha->bios_status == FLASH_IN_PROGRESS) {
		err = FLASH_IN_PROGRESS;
		goto out1;
	}
	err = request_firmware(&asd_ha->bios_image,
				   filename_ptr,
				   &asd_ha->pcidev->dev);
	if (err) {
		asd_printk("Failed to load bios image file %s, error %d\n",
			   filename_ptr, err);
		err = FAIL_OPEN_BIOS_FILE;
		goto out1;
	}

	hdr_ptr = (struct bios_file_header *)asd_ha->bios_image->data;

	if ((hdr_ptr->contrl_id.vendor != asd_ha->pcidev->vendor ||
		hdr_ptr->contrl_id.device != asd_ha->pcidev->device) &&
		(hdr_ptr->contrl_id.sub_vendor != asd_ha->pcidev->vendor ||
		hdr_ptr->contrl_id.sub_device != asd_ha->pcidev->device)) {

		ASD_DPRINTK("The PCI vendor or device id does not match\n");
		ASD_DPRINTK("vendor=%x dev=%x sub_vendor=%x sub_dev=%x"
		" pci vendor=%x pci dev=%x\n",
		hdr_ptr->contrl_id.vendor,
		hdr_ptr->contrl_id.device,
		hdr_ptr->contrl_id.sub_vendor,
		hdr_ptr->contrl_id.sub_device,
		asd_ha->pcidev->vendor,
		asd_ha->pcidev->device);
		err = FAIL_CHECK_PCI_ID;
		goto out2;
	}

	if (hdr_ptr->filelen != asd_ha->bios_image->size) {
		err = FAIL_FILE_SIZE;
		goto out2;
	}

	/* calculate checksum */
	for (i = 0; i < hdr_ptr->filelen; i++)
		csum += asd_ha->bios_image->data[i];

	if ((csum & 0x0000ffff) != hdr_ptr->checksum) {
		ASD_DPRINTK("BIOS file checksum mismatch\n");
		err = FAIL_CHECK_SUM;
		goto out2;
	}
	if (flash_command == FLASH_CMD_UPDATE) {
		asd_ha->bios_status = FLASH_IN_PROGRESS;
		err = asd_write_flash_seg(asd_ha,
			&asd_ha->bios_image->data[sizeof(*hdr_ptr)],
			0, hdr_ptr->filelen-sizeof(*hdr_ptr));
		if (!err)
			err = asd_verify_flash_seg(asd_ha,
				&asd_ha->bios_image->data[sizeof(*hdr_ptr)],
				0, hdr_ptr->filelen-sizeof(*hdr_ptr));
	} else {
		asd_ha->bios_status = FLASH_IN_PROGRESS;
		err = asd_verify_flash_seg(asd_ha,
			&asd_ha->bios_image->data[sizeof(header)],
			0, hdr_ptr->filelen-sizeof(header));
	}

out2:
	release_firmware(asd_ha->bios_image);
out1:
	kfree(cmd_ptr);
out:
	asd_ha->bios_status = err;

	if (!err)
		return count;
	else
		return -err;
}
Ejemplo n.º 24
0
static int mt76x2u_mcu_load_firmware(struct mt76x2_dev *dev)
{
	u32 val, dlm_offset = MT76U_MCU_DLM_OFFSET;
	const struct mt76x2_fw_header *hdr;
	int err, len, ilm_len, dlm_len;
	const struct firmware *fw;

	err = request_firmware(&fw, MT7662U_FIRMWARE, dev->mt76.dev);
	if (err < 0)
		return err;

	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
		err = -EINVAL;
		goto out;
	}

	hdr = (const struct mt76x2_fw_header *)fw->data;
	ilm_len = le32_to_cpu(hdr->ilm_len);
	dlm_len = le32_to_cpu(hdr->dlm_len);
	len = sizeof(*hdr) + ilm_len + dlm_len;
	if (fw->size != len) {
		err = -EINVAL;
		goto out;
	}

	val = le16_to_cpu(hdr->fw_ver);
	dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n",
		 (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf);

	val = le16_to_cpu(hdr->build_ver);
	dev_info(dev->mt76.dev, "Build: %x\n", val);
	dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);

	/* vendor reset */
	mt76u_mcu_fw_reset(&dev->mt76);
	usleep_range(5000, 10000);

	/* enable USB_DMA_CFG */
	val = MT_USB_DMA_CFG_RX_BULK_EN |
	      MT_USB_DMA_CFG_TX_BULK_EN |
	      FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20);
	mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
	/* enable FCE to send in-band cmd */
	mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
	/* FCE tx_fs_base_ptr */
	mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
	/* FCE tx_fs_max_cnt */
	mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1);
	/* FCE pdma enable */
	mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
	/* FCE skip_fs_en */
	mt76_wr(dev, MT_FCE_SKIP_FS, 0x3);

	/* load ILM */
	err = mt76u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr),
				     ilm_len, MCU_FW_URB_MAX_PAYLOAD,
				     MT76U_MCU_ILM_OFFSET);
	if (err < 0) {
		err = -EIO;
		goto out;
	}

	/* load DLM */
	if (mt76xx_rev(dev) >= MT76XX_REV_E3)
		dlm_offset += 0x800;
	err = mt76u_mcu_fw_send_data(&dev->mt76,
				     fw->data + sizeof(*hdr) + ilm_len,
				     dlm_len, MCU_FW_URB_MAX_PAYLOAD,
				     dlm_offset);
	if (err < 0) {
		err = -EIO;
		goto out;
	}

	mt76x2u_mcu_load_ivb(dev);
	if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 100)) {
		dev_err(dev->mt76.dev, "firmware failed to start\n");
		err = -ETIMEDOUT;
		goto out;
	}

	mt76_set(dev, MT_MCU_COM_REG0, BIT(1));
	/* enable FCE to send in-band cmd */
	mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
	dev_dbg(dev->mt76.dev, "firmware running\n");

out:
	release_firmware(fw);
	return err;
}
Ejemplo n.º 25
0
static ssize_t pm8001_store_update_fw(struct device *cdev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct Scsi_Host *shost = class_to_shost(cdev);
	struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
	char *cmd_ptr, *filename_ptr;
	int res, i;
	int flash_command = FLASH_CMD_NONE;
	int err = 0;
	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	cmd_ptr = kzalloc(count*2, GFP_KERNEL);

	if (!cmd_ptr) {
		err = FAIL_OUT_MEMORY;
		goto out;
	}

	filename_ptr = cmd_ptr + count;
	res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr);
	if (res != 2) {
		err = FAIL_PARAMETERS;
		goto out1;
	}

	for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) {
		if (!memcmp(flash_command_table[i].command,
				 cmd_ptr, strlen(cmd_ptr))) {
			flash_command = flash_command_table[i].code;
			break;
		}
	}
	if (flash_command == FLASH_CMD_NONE) {
		err = FAIL_PARAMETERS;
		goto out1;
	}

	if (pm8001_ha->fw_status == FLASH_IN_PROGRESS) {
		err = FLASH_IN_PROGRESS;
		goto out1;
	}
	err = request_firmware(&pm8001_ha->fw_image,
			       filename_ptr,
			       pm8001_ha->dev);

	if (err) {
		PM8001_FAIL_DBG(pm8001_ha,
//			pm8001_printk("Failed to load firmware image file %s,"
;
		err = FAIL_OPEN_BIOS_FILE;
		goto out1;
	}

	switch (flash_command) {
	case FLASH_CMD_UPDATE:
		pm8001_ha->fw_status = FLASH_IN_PROGRESS;
		err = pm8001_update_flash(pm8001_ha);
		break;
	case FLASH_CMD_SET_NVMD:
		pm8001_ha->fw_status = FLASH_IN_PROGRESS;
		err = pm8001_set_nvmd(pm8001_ha);
		break;
	default:
		pm8001_ha->fw_status = FAIL_PARAMETERS;
		err = FAIL_PARAMETERS;
		break;
	}
	release_firmware(pm8001_ha->fw_image);
out1:
	kfree(cmd_ptr);
out:
	pm8001_ha->fw_status = err;

	if (!err)
		return count;
	else
		return -err;
}
Ejemplo n.º 26
0
int mt76x2u_mcu_set_radio_state(struct mt76x2_dev *dev, bool val)
{
	struct {
		__le32 mode;
		__le32 level;
	} __packed __aligned(4) msg = {
		.mode = cpu_to_le32(val ? RADIO_ON : RADIO_OFF),
		.level = cpu_to_le32(0),
	};
	struct sk_buff *skb;

	skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg));
	if (!skb)
		return -ENOMEM;
	return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_POWER_SAVING_OP,
				  false);
}

int mt76x2u_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level,
			u8 channel)
{
	struct {
		u8 cr_mode;
		u8 temp;
		u8 ch;
		u8 _pad0;
		__le32 cfg;
	} __packed __aligned(4) msg = {
		.cr_mode = type,
		.temp = temp_level,
		.ch = channel,
	};
	struct sk_buff *skb;
	u32 val;

	val = BIT(31);
	val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff;
	val |= (mt76x2_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00;
	msg.cfg = cpu_to_le32(val);

	/* first set the channel without the extension channel info */
	skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg));
	if (!skb)
		return -ENOMEM;
	return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_LOAD_CR, true);
}

int mt76x2u_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw,
			    u8 bw_index, bool scan)
{
	struct {
		u8 idx;
		u8 scan;
		u8 bw;
		u8 _pad0;

		__le16 chainmask;
		u8 ext_chan;
		u8 _pad1;

	} __packed __aligned(4) msg = {
		.idx = channel,
		.scan = scan,
		.bw = bw,
		.chainmask = cpu_to_le16(dev->chainmask),
	};
	struct sk_buff *skb;

	/* first set the channel without the extension channel info */
	skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg));
	if (!skb)
		return -ENOMEM;

	mt76u_mcu_send_msg(&dev->mt76, skb, CMD_SWITCH_CHANNEL_OP, true);

	usleep_range(5000, 10000);

	msg.ext_chan = 0xe0 + bw_index;
	skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg));
	if (!skb)
		return -ENOMEM;

	return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_SWITCH_CHANNEL_OP, true);
}

int mt76x2u_mcu_calibrate(struct mt76x2_dev *dev, enum mcu_calibration type,
			  u32 val)
{
	struct {
		__le32 id;
		__le32 value;
	} __packed __aligned(4) msg = {
		.id = cpu_to_le32(type),
		.value = cpu_to_le32(val),
	};
	struct sk_buff *skb;

	skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg));
	if (!skb)
		return -ENOMEM;
	return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_CALIBRATION_OP, true);
}

int mt76x2u_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain,
			  bool force)
{
	struct {
		__le32 channel;
		__le32 gain_val;
	} __packed __aligned(4) msg = {
		.channel = cpu_to_le32(channel),
		.gain_val = cpu_to_le32(gain),
	};
	struct sk_buff *skb;

	if (force)
		msg.channel |= cpu_to_le32(BIT(31));

	skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg));
	if (!skb)
		return -ENOMEM;
	return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_INIT_GAIN_OP, true);
}

int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap,
				bool ext, int rssi, u32 false_cca)
{
	struct {
		__le32 channel;
		__le32 rssi_val;
		__le32 false_cca_val;
	} __packed __aligned(4) msg = {
		.rssi_val = cpu_to_le32(rssi),
		.false_cca_val = cpu_to_le32(false_cca),
	};
	struct sk_buff *skb;
	u32 val = channel;

	if (ap)
		val |= BIT(31);
	if (ext)
		val |= BIT(30);
	msg.channel = cpu_to_le32(val);

	skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg));
	if (!skb)
		return -ENOMEM;
	return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_DYNC_VGA_OP, true);
}

int mt76x2u_mcu_tssi_comp(struct mt76x2_dev *dev,
			  struct mt76x2_tssi_comp *tssi_data)
{
	struct {
		__le32 id;
		struct mt76x2_tssi_comp data;
	} __packed __aligned(4) msg = {
		.id = cpu_to_le32(MCU_CAL_TSSI_COMP),
		.data = *tssi_data,
	};
	struct sk_buff *skb;

	skb = mt76u_mcu_msg_alloc(&msg, sizeof(msg));
	if (!skb)
		return -ENOMEM;
	return mt76u_mcu_send_msg(&dev->mt76, skb, CMD_CALIBRATION_OP, true);
}

static void mt76x2u_mcu_load_ivb(struct mt76x2_dev *dev)
{
	mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
			     USB_DIR_OUT | USB_TYPE_VENDOR,
			     0x12, 0, NULL, 0);
}

static void mt76x2u_mcu_enable_patch(struct mt76x2_dev *dev)
{
	struct mt76_usb *usb = &dev->mt76.usb;
	const u8 data[] = {
		0x6f, 0xfc, 0x08, 0x01,
		0x20, 0x04, 0x00, 0x00,
		0x00, 0x09, 0x00,
	};

	memcpy(usb->data, data, sizeof(data));
	mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
			     USB_DIR_OUT | USB_TYPE_CLASS,
			     0x12, 0, usb->data, sizeof(data));
}

static void mt76x2u_mcu_reset_wmt(struct mt76x2_dev *dev)
{
	struct mt76_usb *usb = &dev->mt76.usb;
	u8 data[] = {
		0x6f, 0xfc, 0x05, 0x01,
		0x07, 0x01, 0x00, 0x04
	};

	memcpy(usb->data, data, sizeof(data));
	mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
			     USB_DIR_OUT | USB_TYPE_CLASS,
			     0x12, 0, usb->data, sizeof(data));
}

static int mt76x2u_mcu_load_rom_patch(struct mt76x2_dev *dev)
{
	bool rom_protect = !is_mt7612(dev);
	struct mt76x2_patch_header *hdr;
	u32 val, patch_mask, patch_reg;
	const struct firmware *fw;
	int err;

	if (rom_protect &&
	    !mt76_poll_msec(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) {
		dev_err(dev->mt76.dev,
			"could not get hardware semaphore for ROM PATCH\n");
		return -ETIMEDOUT;
	}

	if (mt76xx_rev(dev) >= MT76XX_REV_E3) {
		patch_mask = BIT(0);
		patch_reg = MT_MCU_CLOCK_CTL;
	} else {
		patch_mask = BIT(1);
		patch_reg = MT_MCU_COM_REG0;
	}

	if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) {
		dev_info(dev->mt76.dev, "ROM patch already applied\n");
		return 0;
	}

	err = request_firmware(&fw, MT7662U_ROM_PATCH, dev->mt76.dev);
	if (err < 0)
		return err;

	if (!fw || !fw->data || fw->size <= sizeof(*hdr)) {
		dev_err(dev->mt76.dev, "failed to load firmware\n");
		err = -EIO;
		goto out;
	}

	hdr = (struct mt76x2_patch_header *)fw->data;
	dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time);

	/* enable USB_DMA_CFG */
	val = MT_USB_DMA_CFG_RX_BULK_EN |
	      MT_USB_DMA_CFG_TX_BULK_EN |
	      FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20);
	mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);

	/* vendor reset */
	mt76u_mcu_fw_reset(&dev->mt76);
	usleep_range(5000, 10000);

	/* enable FCE to send in-band cmd */
	mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
	/* FCE tx_fs_base_ptr */
	mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
	/* FCE tx_fs_max_cnt */
	mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1);
	/* FCE pdma enable */
	mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
	/* FCE skip_fs_en */
	mt76_wr(dev, MT_FCE_SKIP_FS, 0x3);

	err = mt76u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr),
				     fw->size - sizeof(*hdr),
				     MCU_ROM_PATCH_MAX_PAYLOAD,
				     MT76U_MCU_ROM_PATCH_OFFSET);
	if (err < 0) {
		err = -EIO;
		goto out;
	}

	mt76x2u_mcu_enable_patch(dev);
	mt76x2u_mcu_reset_wmt(dev);
	mdelay(20);

	if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 100)) {
		dev_err(dev->mt76.dev, "failed to load ROM patch\n");
		err = -ETIMEDOUT;
	}

out:
	if (rom_protect)
		mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1);
	release_firmware(fw);
	return err;
}
Ejemplo n.º 27
0
/* Download either STA or AP firmware into the card. */
static int
orinoco_dl_firmware(struct orinoco_private *priv,
                    const struct fw_info *fw,
                    int ap)
{
    /* Plug Data Area (PDA) */
    __le16 *pda;

    struct hermes *hw = &priv->hw;
    const struct firmware *fw_entry;
    const struct orinoco_fw_header *hdr;
    const unsigned char *first_block;
    const void *end;
    const char *firmware;
    const char *fw_err;
    struct device *dev = priv->dev;
    int err = 0;

    pda = kzalloc(fw->pda_size, GFP_KERNEL);
    if (!pda)
        return -ENOMEM;

    if (ap)
        firmware = fw->ap_fw;
    else
        firmware = fw->sta_fw;

    dev_dbg(dev, "Attempting to download firmware %s\n", firmware);

    /* Read current plug data */
    err = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
    dev_dbg(dev, "Read PDA returned %d\n", err);
    if (err)
        goto free;

    if (!orinoco_cached_fw_get(priv, false)) {
        err = request_firmware(&fw_entry, firmware, priv->dev);

        if (err) {
            dev_err(dev, "Cannot find firmware %s\n", firmware);
            err = -ENOENT;
            goto free;
        }
    } else
        fw_entry = orinoco_cached_fw_get(priv, false);

    hdr = (const struct orinoco_fw_header *) fw_entry->data;

    fw_err = validate_fw(hdr, fw_entry->size);
    if (fw_err) {
        dev_warn(dev, "Invalid firmware image detected (%s). "
                 "Aborting download\n", fw_err);
        err = -EINVAL;
        goto abort;
    }

    /* Enable aux port to allow programming */
    err = hw->ops->program_init(hw, le32_to_cpu(hdr->entry_point));
    dev_dbg(dev, "Program init returned %d\n", err);
    if (err != 0)
        goto abort;

    /* Program data */
    first_block = (fw_entry->data +
                   le16_to_cpu(hdr->headersize) +
                   le32_to_cpu(hdr->block_offset));
    end = fw_entry->data + fw_entry->size;

    err = hermes_program(hw, first_block, end);
    dev_dbg(dev, "Program returned %d\n", err);
    if (err != 0)
        goto abort;

    /* Update production data */
    first_block = (fw_entry->data +
                   le16_to_cpu(hdr->headersize) +
                   le32_to_cpu(hdr->pdr_offset));

    err = hermes_apply_pda_with_defaults(hw, first_block, end, pda,
                                         &pda[fw->pda_size / sizeof(*pda)]);
    dev_dbg(dev, "Apply PDA returned %d\n", err);
    if (err)
        goto abort;

    /* Tell card we've finished */
    err = hw->ops->program_end(hw);
    dev_dbg(dev, "Program end returned %d\n", err);
    if (err != 0)
        goto abort;

    /* Check if we're running */
    dev_dbg(dev, "hermes_present returned %d\n", hermes_present(hw));

abort:
    /* If we requested the firmware, release it. */
    if (!orinoco_cached_fw_get(priv, false))
        release_firmware(fw_entry);

free:
    kfree(pda);
    return err;
}
Ejemplo n.º 28
0
static const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
{
	struct lme2510_state *st = d->priv;
	struct usb_device *udev = d->udev;
	const struct firmware *fw = NULL;
	const char *fw_lme;
	int ret = 0;

	cold = (cold > 0) ? (cold & 1) : 0;

	switch (le16_to_cpu(udev->descriptor.idProduct)) {
	case 0x1122:
		switch (st->dvb_usb_lme2510_firmware) {
		default:
		case TUNER_S0194:
			fw_lme = fw_s0194;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0) {
				st->dvb_usb_lme2510_firmware = TUNER_S0194;
				cold = 0;
				break;
			}
			/* fall through */
		case TUNER_LG:
			fw_lme = fw_lg;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0) {
				st->dvb_usb_lme2510_firmware = TUNER_LG;
				break;
			}
			st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
			break;
		}
		break;
	case 0x1120:
		switch (st->dvb_usb_lme2510_firmware) {
		default:
		case TUNER_S7395:
			fw_lme = fw_c_s7395;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0) {
				st->dvb_usb_lme2510_firmware = TUNER_S7395;
				cold = 0;
				break;
			}
			/* fall through */
		case TUNER_LG:
			fw_lme = fw_c_lg;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0) {
				st->dvb_usb_lme2510_firmware = TUNER_LG;
				break;
			}
			/* fall through */
		case TUNER_S0194:
			fw_lme = fw_c_s0194;
			ret = request_firmware(&fw, fw_lme, &udev->dev);
			if (ret == 0) {
				st->dvb_usb_lme2510_firmware = TUNER_S0194;
				break;
			}
			st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
			cold = 0;
			break;
		}
		break;
	case 0x22f0:
		fw_lme = fw_c_rs2000;
		st->dvb_usb_lme2510_firmware = TUNER_RS2000;
		break;
	default:
		fw_lme = fw_c_s7395;
	}

	release_firmware(fw);

	if (cold) {
		dvb_usb_lme2510_firmware = st->dvb_usb_lme2510_firmware;
		info("FRM Changing to %s firmware", fw_lme);
		lme_coldreset(d);
		return NULL;
	}

	return fw_lme;
}
static u8 *edid_load(struct drm_connector *connector, const char *name,
			const char *connector_name)
{
	const struct firmware *fw = NULL;
	const u8 *fwdata;
	u8 *edid;
	int fwsize, builtin;
	int i, valid_extensions = 0;
	bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);

	builtin = 0;
	for (i = 0; i < GENERIC_EDIDS; i++) {
		if (strcmp(name, generic_edid_name[i]) == 0) {
			fwdata = generic_edid[i];
			fwsize = sizeof(generic_edid[i]);
			builtin = 1;
			break;
		}
	}
	if (!builtin) {
		struct platform_device *pdev;
		int err;

		pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
		if (IS_ERR(pdev)) {
			DRM_ERROR("Failed to register EDID firmware platform device "
				  "for connector \"%s\"\n", connector_name);
			return ERR_CAST(pdev);
		}

		err = request_firmware(&fw, name, &pdev->dev);
		platform_device_unregister(pdev);
		if (err) {
			DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n",
				  name, err);
			return ERR_PTR(err);
		}

		fwdata = fw->data;
		fwsize = fw->size;
	}

	if (edid_size(fwdata, fwsize) != fwsize) {
		DRM_ERROR("Size of EDID firmware \"%s\" is invalid "
			  "(expected %d, got %d\n", name,
			  edid_size(fwdata, fwsize), (int)fwsize);
		edid = ERR_PTR(-EINVAL);
		goto out;
	}

	edid = kmemdup(fwdata, fwsize, GFP_KERNEL);
	if (edid == NULL) {
		edid = ERR_PTR(-ENOMEM);
		goto out;
	}

	if (!drm_edid_block_valid(edid, 0, print_bad_edid)) {
		connector->bad_edid_counter++;
		DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
		    name);
		kfree(edid);
		edid = ERR_PTR(-EINVAL);
		goto out;
	}

	for (i = 1; i <= edid[0x7e]; i++) {
		if (i != valid_extensions + 1)
			memcpy(edid + (valid_extensions + 1) * EDID_LENGTH,
			    edid + i * EDID_LENGTH, EDID_LENGTH);
		if (drm_edid_block_valid(edid + i * EDID_LENGTH, i, print_bad_edid))
			valid_extensions++;
	}

	if (valid_extensions != edid[0x7e]) {
		u8 *new_edid;

		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
		DRM_INFO("Found %d valid extensions instead of %d in EDID data "
		    "\"%s\" for connector \"%s\"\n", valid_extensions,
		    edid[0x7e], name, connector_name);
		edid[0x7e] = valid_extensions;

		new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
				    GFP_KERNEL);
		if (new_edid)
			edid = new_edid;
	}

	DRM_INFO("Got %s EDID base block and %d extension%s from "
	    "\"%s\" for connector \"%s\"\n", builtin ? "built-in" :
	    "external", valid_extensions, valid_extensions == 1 ? "" : "s",
	    name, connector_name);

out:
	if (fw)
		release_firmware(fw);
	return edid;
}
Ejemplo n.º 30
0
static int s2250loader_probe(struct usb_interface *interface,
				const struct usb_device_id *id)
{
	struct usb_device *usbdev;
	int minor, ret;
	pdevice_extension_t s = NULL;
	const struct firmware *fw;

	usbdev = usb_get_dev(interface_to_usbdev(interface));
	if (!usbdev) {
		printk(KERN_ERR "Enter s2250loader_probe failed\n");
		return -1;
	}
	printk(KERN_INFO "Enter s2250loader_probe 2.6 kernel\n");
	printk(KERN_INFO "vendor id 0x%x, device id 0x%x devnum:%d\n",
	   usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
	   usbdev->devnum);

	if (usbdev->descriptor.bNumConfigurations != 1) {
		printk(KERN_ERR "can't handle multiple config\n");
		return -1;
	}
	down(&s2250_dev_table_mutex);

	for (minor = 0; minor < MAX_DEVICES; minor++) {
		if (s2250_dev_table[minor] == NULL)
			break;
	}

	if (minor < 0 || minor >= MAX_DEVICES) {
		printk(KERN_ERR "Invalid minor: %d\n", minor);
		goto failed;
	}

	/* Allocate dev data structure */
	s = kmalloc(sizeof(device_extension_t), GFP_KERNEL);
	if (s == NULL) {
		printk(KERN_ERR "Out of memory\n");
		goto failed;
	}
	s2250_dev_table[minor] = s;

	printk(KERN_INFO "s2250loader_probe: Device %d on Bus %d Minor %d\n",
		usbdev->devnum, usbdev->bus->busnum, minor);

	memset(s, 0, sizeof(device_extension_t));
	s->usbdev = usbdev;
	printk(KERN_INFO "loading 2250 loader\n");

	kref_init(&(s->kref));

	up(&s2250_dev_table_mutex);

	if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
		printk(KERN_ERR
			"s2250: unable to load firmware from file \"%s\"\n",
			S2250_LOADER_FIRMWARE);
		goto failed2;
	}
	ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
	release_firmware(fw);
	if (0 != ret) {
		printk(KERN_ERR "loader download failed\n");
		goto failed2;
	}

	if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) {
		printk(KERN_ERR
			"s2250: unable to load firmware from file \"%s\"\n",
			S2250_FIRMWARE);
		goto failed2;
	}
	ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
	release_firmware(fw);
	if (0 != ret) {
		printk(KERN_ERR "firmware_s2250 download failed\n");
		goto failed2;
	}

	usb_set_intfdata(interface, s);
	return 0;

failed:
	up(&s2250_dev_table_mutex);
failed2:
	if (s)
		kref_put(&(s->kref), s2250loader_delete);

	printk(KERN_ERR "probe failed\n");
	return -1;
}