Example #1
0
File: irq.c Project: skordal/mordax
void irq_object_destroy(struct irq_object * object)
{
	if(object->listener)
	{
		context_set_syscall_retval(object->listener->context, (void *) -EIDRM);
		scheduler_move_thread_to_running(object->listener);
	}

	irq_disable(object->irq);
	irq_unregister(object->irq);

	mm_free(object);
}
static __exit void realview_irq_exit(void)
{
	u32_t i;

	for(i = 0; i < ARRAY_SIZE(realview_irqs); i++)
	{
		if(!irq_unregister(&realview_irqs[i]))
		{
			LOG_E("failed to unregister irq '%s'", realview_irqs[i].name);
		}
	}

	/* disable irq and fiq */
	irq_disable();
	fiq_disable();
}
Example #3
0
static inline void lpc_usb_close_device(CORE* core)
{
    int i;
    //disable interrupts
    NVIC_DisableIRQ(USB_IRQn);
    irq_unregister(USB_IRQn);
#if (USB_SOFT_CONNECT)
    //disable pullap
    LPC_USB->DEVCMDSTAT &= ~USB_DEVCMDSTAT_DCON;
#endif
    //close all endpoints
    for (i = 0; i < USB_EP_COUNT_MAX; ++i)
    {
        if (core->usb.out[i] != NULL)
            lpc_usb_close_ep(core, i);
        if (core->usb.in[i] != NULL)
            lpc_usb_close_ep(core, USB_EP_IN | i);
    }
    //Mask all interrupts
    LPC_USB->INTEN = 0;
    //disable device
    LPC_USB->DEVCMDSTAT &= ~USB_DEVCMDSTAT_DEV_EN;

    //power down
    //turn clock off
    LPC_SYSCON->SYSAHBCLKCTRL &= ~((1 << SYSCON_SYSAHBCLKCTRL_USB_POS) | (1 << SYSCON_SYSAHBCLKCTRL_USBRAM_POS));
    //power down
    LPC_SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_USBPAD_PD;
#if (USB_DEDICATED_PLL)
    LPC_SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_USBPLL_PD;
#endif

    //disable pins
    lpc_pin_request_inside(core, HAL_REQ(HAL_PIN, IPC_CLOSE), VBUS, 0, 0);
#if (USB_SOFT_CONNECT)
    lpc_pin_request_inside(core, HAL_REQ(HAL_PIN, IPC_CLOSE), SCONNECT, 0, 0);
#endif
}
Example #4
0
static inline void lpc_sdmmc_close(CORE* core)
{
    if (!core->sdmmc.active)
    {
        error(ERROR_NOT_CONFIGURED);
        return;
    }
    //disable interrupts
    NVIC_DisableIRQ(SDIO_IRQn);

    lpc_sdmmc_flush(core);
    sdmmcs_reset(&core->sdmmc.sdmmcs);

    irq_unregister(SDIO_IRQn);
    //mask all interrupts
    LPC_SDMMC->CTRL &= ~SDMMC_CTRL_INT_ENABLE_Msk;
    LPC_SDMMC->INTMASK = 0;
    LPC_CGU->BASE_SDIO_CLK = CGU_BASE_SDIO_CLK_PD_Msk;

    free(core->sdmmc.descr);
    core->sdmmc.descr = NULL;
    core->sdmmc.active = false;
    core->sdmmc.user = INVALID_HANDLE;
}
Example #5
0
/** Register a new PCI ATA channel.
 * @param pci_device	PCI device the channel is on.
 * @param idx		Channel index.
 * @param ctrl_base	Control registers base address.
 * @param cmd_base	Command registers base address.
 * @param bm_base	Bus master base address.
 * @param irq		IRQ number.
 * @return		Pointer to ATA channel structure if present. */
static ata_channel_t *pci_ata_channel_add(pci_device_t *pci_device, int idx, uint32_t ctrl_base,
                                          uint32_t cmd_base, uint32_t bm_base, uint32_t irq) {
	uint16_t pci_cmd_old, pci_cmd_new;
	pci_ata_channel_t *channel;
	bool dma = true;
	status_t ret;

	/* Configure the PCI device appropriately. */
	pci_cmd_old = pci_cmd_new = pci_config_read16(pci_device, PCI_CONFIG_COMMAND);
	pci_cmd_new &= ~PCI_COMMAND_INT_DISABLE;
	pci_cmd_new |= (PCI_COMMAND_IO | PCI_COMMAND_BUS_MASTER);
	if(pci_cmd_new != pci_cmd_old) {
		pci_config_write16(pci_device, PCI_CONFIG_COMMAND, pci_cmd_new);
		kprintf(LOG_DEBUG, "ata: reconfigured PCI device %d:%02x.%d (old: 0x%04x, new: 0x%04x)\n",
		        pci_device->bus, pci_device->device, pci_device->function,
		        pci_cmd_old, pci_cmd_new);
        }

	/* Check presence by writing a value to the low LBA port on the channel,
	 * then reading it back. If the value is the same, it is present. */
	out8(cmd_base + ATA_CMD_REG_LBA_LOW, 0xAB);
	if(in8(cmd_base + ATA_CMD_REG_LBA_LOW) != 0xAB) {
		if(pci_cmd_new != pci_cmd_old) {
			pci_config_write16(pci_device, PCI_CONFIG_COMMAND, pci_cmd_old);
		}
		return NULL;
	}

	/* Allocate our information structure. */
	channel = kmalloc(sizeof(*channel), MM_WAIT);
	channel->channel = NULL;
	channel->pci_device = pci_device;
	channel->ctrl_base = ctrl_base;
	channel->cmd_base = cmd_base;
	channel->bus_master_base = bm_base + (idx * 8);
	channel->irq = irq;
	channel->prdt = NULL;

	/* If the bus master is in simplex mode, disable DMA on the second
	 * channel. According to the Haiku code, Intel controllers use this for
	 * something other than simplex mode. */
	if(pci_device->vendor_id != 0x8086) {
		if(in8(bm_base + PCI_ATA_BM_REG_STATUS) & PCI_ATA_BM_STATUS_SIMPLEX && idx > 1) {
			dma = false;
		}
	}

	/* Allocate a PRDT if necessary. */
	if(dma) {
		phys_alloc(PRDT_SIZE, 0, 0, 0, (phys_ptr_t)0x100000000, MM_WAIT, &channel->prdt_phys);
		channel->prdt = phys_map(channel->prdt_phys, PRDT_SIZE, MM_WAIT);
	}

	/* Register the IRQ handler. */
	ret = irq_register(channel->irq, pci_ata_irq_handler, NULL, channel);
	if(ret != STATUS_SUCCESS) {
		kprintf(LOG_WARN, "ata: failed to register PCI ATA IRQ handler %u\n", channel->irq);
		if(dma) {
			phys_unmap(channel->prdt, PRDT_SIZE, true);
			phys_free(channel->prdt_phys, PRDT_SIZE);
		}
		kfree(channel);
		return NULL;
	}

	/* Try to register the ATA channel. */
	channel->channel = ata_sff_channel_add(pci_device->node, idx, &pci_ata_channel_ops, channel,
	                                       dma, PRDT_ENTRIES, (phys_ptr_t)0x100000000);
	if(!channel->channel) {
		irq_unregister(channel->irq, pci_ata_irq_handler, NULL, channel);
		if(dma) {
			phys_unmap(channel->prdt, PRDT_SIZE, true);
			phys_free(channel->prdt_phys, PRDT_SIZE);
		}
		kfree(channel);
		return NULL;
	}

	return channel->channel;
}