Re: [RFC] pciehp: Add archdata setting

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Apr 16, 2012 at 12:32 AM, Hiroo Matsumoto
<matsumoto.hiroo@xxxxxxxxxxxxxx> wrote:
> Hi, Bjorn
>
>
> I wrote a code with bus_register_notifier().
> A function that calls bus_register_notifer() is called from rootfs_initcall
> as well as amd_iommu is.
>
> Please review this.
>
>
> Regards.
>
> Hiroo MATSUMOTO
>
>
>> Hi, Bjorn
>>
>>
>> Thanks for your research and comment.
>>
>> As you said, a way of registering code with bus_register_notifier(), which
>> will be called in device_add(), is better one than pcibios_enable_device().
>> I will try to write code with bus_register_notifier().
>>
>>
>> Regards.
>>
>> Hiroo MATSUMOTO
>>
>>> On Wed, Apr 11, 2012 at 11:00 PM, Hiroo Matsumoto
>>> <matsumoto.hiroo@xxxxxxxxxxxxxx> wrote:
>>>>
>>>> Hi, Kaneshige
>>>>
>>>>
>>>> You are right!
>>>> Setting dma_ops in pcibios_enable_device is a nice way.
>>>> In PCI driver, pci_enable_device_xxx that calls pcibios_enable_device is
>>>> called before checking archdata.dma_ops.
>>>>
>>>> I added code of checking and setting dma_ops to pcibios_enable_device in
>>>> arch/powerpc/kernel/pci-common.c.
>>>> It works good.
>>>
>>>
>>> When I researched this, I thought the best route was to use the
>>> bus_register_notifier() path, as amd_iommu_init_notifier() does.
>>>
>>> We're filling in a struct device field, not a PCI field, and
>>> bus_register_notifier() seems like a more generic path than relying on
>>> pcibios_enable_device().
>>>
>>> Bjorn
>>>
>>>
>>
>
> Signed-off-by: Hiroo MATSUMOTO <matsumoto.hiroo@xxxxxxxxxxxxxx>
> diff --git a/arch/powerpc/kernel/pci-common.c
> b/arch/powerpc/kernel/pci-common.c
> index 32656f1..1fe1e25 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -1083,6 +1083,17 @@ void __devinit pcibios_setup_bus_self(struct pci_bus
> *bus)
>                ppc_md.pci_dma_bus_setup(bus);
>  }
>
> +static inline void pcibios_set_dma_ops(struct pci_dev *dev)
> +{
> +       /* Hook up default DMA ops */
> +       set_dma_ops(&dev->dev, pci_dma_ops);
> +       set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
> +
> +       /* Additional platform DMA/iommu setup */
> +       if (ppc_md.pci_dma_dev_setup)
> +               ppc_md.pci_dma_dev_setup(dev);
> +}
> +
>  void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
>  {
>        struct pci_dev *dev;
> @@ -1102,13 +1113,7 @@ void __devinit pcibios_setup_bus_devices(struct
> pci_bus *bus)
>                 */
>                set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
>
> -               /* Hook up default DMA ops */
> -               set_dma_ops(&dev->dev, pci_dma_ops);
> -               set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
> -
> -               /* Additional platform DMA/iommu setup */
> -               if (ppc_md.pci_dma_dev_setup)
> -                       ppc_md.pci_dma_dev_setup(dev);
> +               pcibios_set_dma_ops(dev);
>
>                /* Read default IRQs and fixup if necessary */
>                pci_read_irq_line(dev);
> @@ -1749,3 +1754,33 @@ static void fixup_hide_host_resource_fsl(struct
> pci_dev *dev)
>  }
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID,
> fixup_hide_host_resource_fsl);
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID,
> fixup_hide_host_resource_fsl);
> +
> +static int pcibios_device_change_notifier(struct notifier_block *nb,
> +                                         unsigned long action, void *data)
> +{
> +       struct pci_dev *dev = to_pci_dev(data);
> +
> +       if (!dev)
> +               return 0;

I don't think you need this check.

> +
> +       switch (action) {
> +       case BUS_NOTIFY_ADD_DEVICE:
> +               if (!get_dma_ops(&dev->dev))
> +                       pcibios_set_dma_ops(dev);
> +               break;
> +       default:
> +               break;

The "default:" case is superfluous.

> +       }
> +
> +       return 0;
> +}
> +
> +static struct notifier_block device_nb = {
> +       .notifier_call = pcibios_device_change_notifier,
> +};
> +
> +static int pcibios_bus_notifier_init(void)
> +{
> +       return bus_register_notifier(&pci_bus_type, &device_nb);
> +}
> +rootfs_initcall(pcibios_bus_notifier_init);

Instead of making this a rootfs_initcall(), can you call
bus_register_notifier() explicitly in pcibios_init()?  That way
pcibios_device_change_notifier() should get called for *all* new PCI
devices, whether we find them at boot-time or they're hot-added later.

If you do that, I think you can move all the
pcibios_setup_bus_devices() code into the
pcibios_device_change_notifier() path, including the NUMA node and IRQ
fixups.

Your patch will also need a changelog.

Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux