[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RFC PATCH 03/19] xen/arm: its: Port ITS driver to xen
Hi Julien, On Fri, Mar 13, 2015 at 5:16 PM, Julien Grall <julien.grall@xxxxxxxxxx> wrote: > Hello Vijay, > > On 02/03/2015 12:30, vijay.kilari@xxxxxxxxx wrote: >> >> @@ -228,10 +242,10 @@ static struct its_collection >> *its_build_mapd_cmd(struct its_cmd_block *cmd, >> struct its_cmd_desc >> *desc) >> { >> unsigned long itt_addr; >> - u8 size = max(order_base_2(desc->its_mapd_cmd.dev->nr_ites), 1); >> + u8 size = max(fls(desc->its_mapd_cmd.dev->nr_ites) - 1, 1); > > > You may want to give a look to get_count_order. > >> >> - itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt); >> - itt_addr = ALIGN(itt_addr, ITS_ITT_ALIGN); >> + itt_addr = __pa(desc->its_mapd_cmd.dev->itt); >> + itt_addr = ((itt_addr) + (ITS_ITT_ALIGN - 1)) & ~(ITS_ITT_ALIGN - 1); > > > You can use ROUNDUP. > > [..] > >> @@ -343,17 +357,23 @@ static int its_queue_full(struct its_node *its) >> static struct its_cmd_block *its_allocate_entry(struct its_node *its) >> { >> struct its_cmd_block *cmd; >> - u32 count = 1000000; /* 1s! */ >> + bool_t timeout = 0; >> + s_time_t deadline = NOW() + MILLISECS(1000); >> >> while (its_queue_full(its)) { >> - count--; >> - if (!count) { >> - pr_err_ratelimited("ITS queue not draining\n"); >> - return NULL; >> + if ( NOW() > deadline ) >> + { >> + timeout = 1; >> + break; >> } >> cpu_relax(); >> udelay(1); >> } >> + if ( timeout ) >> + { >> + its_err("ITS queue not draining\n"); >> + return NULL; >> + } > > > Why do you need to modify the loop? It looks like to me it will work Xen > too. I remember we used similar approach for GICv3. > >> /* >> - * irqchip functions - assumes MSI, mostly. >> - */ >> - >> -static void lpi_set_config(struct its_device *its_dev, u32 hwirq, >> - u32 id, int enable) >> -{ >> - u8 *cfg = page_address(gic_rdists->prop_page) + hwirq - 8192; >> - >> - if (enable) >> - *cfg |= LPI_PROP_ENABLED; >> - else >> - *cfg &= ~LPI_PROP_ENABLED; >> - >> - /* >> - * Make the above write visible to the redistributors. >> - * And yes, we're flushing exactly: One. Single. Byte. >> - * Humpf... >> - */ >> - if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING) >> - __flush_dcache_area(cfg, sizeof(*cfg)); >> - else >> - dsb(ishst); >> - its_send_inv(its_dev, id); >> -} >> - >> -static inline u16 its_msi_get_entry_nr(struct msi_desc *desc) >> -{ >> - return desc->msi_attrib.entry_nr; >> -} >> - >> -static void its_mask_irq(struct irq_data *d) >> -{ >> - struct its_device *its_dev = irq_data_get_irq_handler_data(d); >> - u32 id; >> - >> - /* If MSI, propagate the mask to the RC */ >> - if (IS_ENABLED(CONFIG_PCI_MSI) && d->msi_desc) { >> - id = its_msi_get_entry_nr(d->msi_desc); >> - mask_msi_irq(d); >> - } else { >> - id = d->hwirq; >> - } >> - >> - lpi_set_config(its_dev, d->hwirq, id, 0); >> -} >> - >> -static void its_unmask_irq(struct irq_data *d) >> -{ >> - struct its_device *its_dev = irq_data_get_irq_handler_data(d); >> - u32 id; >> - >> - /* If MSI, propagate the unmask to the RC */ >> - if (IS_ENABLED(CONFIG_PCI_MSI) && d->msi_desc) { >> - id = its_msi_get_entry_nr(d->msi_desc); >> - unmask_msi_irq(d); >> - } else { >> - id = d->hwirq; >> - } >> - >> - lpi_set_config(its_dev, d->hwirq, id, 1); >> -} >> - >> -static void its_eoi_irq(struct irq_data *d) >> -{ >> - gic_write_eoir(d->hwirq); >> -} >> - >> -static int its_set_affinity(struct irq_data *d, const struct cpumask >> *mask_val, >> - bool force) >> -{ >> - unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); >> - struct its_device *its_dev = irq_data_get_irq_handler_data(d); >> - struct its_collection *target_col; >> - u32 id; >> - >> - if (cpu >= nr_cpu_ids) >> - return -EINVAL; >> - >> - target_col = &its_dev->its->collections[cpu]; >> - if (IS_ENABLED(CONFIG_PCI_MSI) && d->msi_desc) >> - id = its_msi_get_entry_nr(d->msi_desc); >> - else >> - id = d->hwirq; >> - its_send_movi(its_dev, target_col, id); >> - its_dev->collection = target_col; >> - >> - return IRQ_SET_MASK_OK; >> -} >> - >> -static struct irq_chip its_irq_chip = { >> - .name = "ITS", >> - .irq_mask = its_mask_irq, >> - .irq_unmask = its_unmask_irq, >> - .irq_eoi = its_eoi_irq, >> - .irq_set_affinity = its_set_affinity, >> -}; >> - > > > Most of those callbacks seems useful to me. Why did you drop them? There is no irq_chip in xen. So thought of removing in completely and adding as separate patch >> >> - >> - >> -static int its_msi_get_vec_count(struct pci_dev *pdev, struct msi_desc >> *desc) >> -{ >> -#ifdef CONFIG_PCI_MSI >> - if (desc->msi_attrib.is_msix) >> - return pci_msix_vec_count(pdev); >> - else >> - return pci_msi_vec_count(pdev); >> -#else >> - return -EINVAL; >> -#endif >> -} >> - >> -int pci_requester_id(struct pci_dev *dev); >> -static int its_msi_setup_irq(struct msi_chip *chip, >> - struct pci_dev *pdev, >> - struct msi_desc *desc) >> -{ >> - struct its_node *its = container_of(chip, struct its_node, msi_chip); >> - struct its_device *its_dev; >> - struct msi_msg msg; >> - unsigned int irq; >> - u64 addr; >> - int hwirq; >> - int err; >> - u32 dev_id = pci_requester_id(pdev); >> - u32 vec_nr; >> - >> - its_dev = its_find_device(its, dev_id); >> - if (!its_dev) { >> - int nvec = its_msi_get_vec_count(pdev, desc); >> - if (WARN_ON(nvec <= 0)) >> - return nvec; >> - its_dev = its_create_device(its, dev_id, nvec); >> - } >> - if (!its_dev) >> - return -ENOMEM; >> - vec_nr = its_msi_get_entry_nr(desc); >> - err = its_alloc_device_irq(its_dev, vec_nr, &hwirq, &irq); >> - if (err) >> - return err; >> - >> - irq_set_msi_desc(irq, desc); >> - irq_set_handler_data(irq, its_dev); >> - >> - addr = its->phys_base + GITS_TRANSLATER; >> - >> - msg.address_lo = (u32)addr; >> - msg.address_hi = (u32)(addr >> 32); >> - msg.data = vec_nr; >> - >> - write_msi_msg(irq, &msg); >> - return 0; >> -} >> - >> -static void its_msi_teardown_irq(struct msi_chip *chip, unsigned int irq) >> -{ >> - struct irq_data *d = irq_get_irq_data(irq); >> - struct its_device *its_dev = irq_data_get_irq_handler_data(d); >> - >> - BUG_ON(d->hwirq < its_dev->lpi_base || /* OMG! */ >> - d->hwirq > (its_dev->lpi_base + its_dev->nr_lpis)); >> - >> - /* Stop the delivery of interrupts */ >> - its_send_discard(its_dev, its_msi_get_entry_nr(d->msi_desc)); >> - >> - /* Mark interrupt index as unused, and clear the mapping */ >> - clear_bit(d->hwirq - its_dev->lpi_base, its_dev->lpi_map); >> - irq_dispose_mapping(irq); >> - >> - /* If all interrupts have been freed, start mopping the floor */ >> - if (bitmap_empty(its_dev->lpi_map, its_dev->nr_lpis)) { >> - its_lpi_free(its_dev->lpi_map, >> - its_dev->lpi_base, >> - its_dev->nr_lpis); >> - >> - /* Unmap device/itt */ >> - its_send_mapd(its_dev, 0); >> - its_free_device(its_dev); >> - } >> -} >> - > > > Those 2 functions seems useful for me. Why did you drop them? These are callbacks registered for msi_chip in linux, Since we have removed msi_chip from its_node structure, these functions are supposed to be removed. Regards Vijay _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |