All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd@arndb.de>
To: linuxppc-dev@ozlabs.org
Cc: paulus@samba.org
Subject: Re: [PATCH 7/7] Celleb: update for PCI
Date: Wed, 26 Sep 2007 14:09:31 +0200	[thread overview]
Message-ID: <200709261409.32231.arnd@arndb.de> (raw)
In-Reply-To: <20070926.134050.1102532600.kouish@swc.toshiba.co.jp>

On Wednesday 26 September 2007, Ishizaki Kou wrote:
> This is a patch kit to support PCI bus on Celleb with new "I/O routines
> for PowerPC." External PCI on Celleb must do explicit synchronization
> with devices (Bus has no automatic synchronization feature).

It seems you are duplicating a lot of
arch/powerpc/platforms/cell/io-workarounds.c, in order to work around
the same problem:

> +static struct celleb_pci_bus *celleb_pci_find(unsigned long vaddr,
> +					      unsigned long paddr)
> +{
> +	int i, j;
> +	struct resource *res;
> +
> +	for (i = 0; i < celleb_pci_count; i++) {
> +		struct celleb_pci_bus *bus = &celleb_pci_busses[i];
> +		struct pci_controller *phb = bus->phb;
> +		if (paddr)
> +			for (j = 0; j < 3; j++) {
> +				res = &phb->mem_resources[j];
> +				if (paddr >= res->start && paddr <= res->end)
> +					return bus;
> +			}
> +		res = &phb->io_resource;
> +		if (vaddr && vaddr >= res->start && vaddr <= res->end)
> +			return bus;
> +	}
> +	return NULL;
> +}
> +
> +static void celleb_io_flush(const PCI_IO_ADDR addr)
> +{
> +	struct celleb_pci_bus *bus;
> +	int token;
> +
> +	token = PCI_GET_ADDR_TOKEN(addr);
> +
> +	if (token && token <= celleb_pci_count)
> +		bus = &celleb_pci_busses[token - 1];
> +	else {
> +		unsigned long vaddr, paddr;
> +		pte_t *ptep;
> +
> +		vaddr = (unsigned long)PCI_FIX_ADDR(addr);
> +		if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
> +			return;
> +
> +		ptep = find_linux_pte(init_mm.pgd, vaddr);
> +		if (ptep == NULL)
> +			paddr = 0;
> +		else
> +			paddr = pte_pfn(*ptep) << PAGE_SHIFT;
> +		bus = celleb_pci_find(vaddr, paddr);
> +
> +		if (bus == NULL)
> +			return;
> +	}
> +
> +	if (bus->dummy_read)
> +		bus->dummy_read(bus->phb);
> +}
> +
> +static u8 celleb_readb(const PCI_IO_ADDR addr)
> +{
> +	u8 val;
> +	val = __do_readb(addr);
> +	celleb_io_flush(addr);
> +	return val;
> +}
> +
> +static u16 celleb_readw(const PCI_IO_ADDR addr)
> +{
> +	u16 val;
> +	val = __do_readw(addr);
> +	celleb_io_flush(addr);
> +	return val;
> +}
> +
> +static u32 celleb_readl(const PCI_IO_ADDR addr)
> +{
> +	u32 val;
> +	val = __do_readl(addr);
> +	celleb_io_flush(addr);
> +	return val;
> +}
> +
> +static u64 celleb_readq(const PCI_IO_ADDR addr)
> +{
> +	u64 val;
> +	val = __do_readq(addr);
> +	celleb_io_flush(addr);
> +	return val;
> +}
> +
> +static u16 celleb_readw_be(const PCI_IO_ADDR addr)
> +{
> +	u16 val;
> +	val = __do_readw_be(addr);
> +	celleb_io_flush(addr);
> +	return val;
> +}
> +
> +static u32 celleb_readl_be(const PCI_IO_ADDR addr)
> +{
> +	u32 val;
> +	val = __do_readl_be(addr);
> +	celleb_io_flush(addr);
> +	return val;
> +}
> +
> +static u64 celleb_readq_be(const PCI_IO_ADDR addr)
> +{
> +	u64 val;
> +	val = __do_readq_be(addr);
> +	celleb_io_flush(addr);
> +	return val;
> +}
> +
> +static void celleb_readsb(const PCI_IO_ADDR addr,
> +			  void *buf, unsigned long count)
> +{
> +	__do_readsb(addr, buf, count);
> +	celleb_io_flush(addr);
> +}
> +
> +static void celleb_readsw(const PCI_IO_ADDR addr,
> +			  void *buf, unsigned long count)
> +{
> +	__do_readsw(addr, buf, count);
> +	celleb_io_flush(addr);
> +}
> +
> +static void celleb_readsl(const PCI_IO_ADDR addr,
> +			  void *buf, unsigned long count)
> +{
> +	__do_readsl(addr, buf, count);
> +	celleb_io_flush(addr);
> +}
> +
> +static void celleb_memcpy_fromio(void *dest,
> +				 const PCI_IO_ADDR src,
> +				 unsigned long n)
> +{
> +	__do_memcpy_fromio(dest, src, n);
> +	celleb_io_flush(src);
> +}
> +
> +static void __iomem *celleb_ioremap(unsigned long addr,
> +				     unsigned long size,
> +				     unsigned long flags)
> +{
> +	struct celleb_pci_bus *bus;
> +	void __iomem *res = __ioremap(addr, size, flags);
> +	int busno;
> +
> +	bus = celleb_pci_find(0, addr);
> +	if (bus != NULL) {
> +		busno = bus - celleb_pci_busses;
> +		PCI_SET_ADDR_TOKEN(res, busno + 1);
> +	}
> +	return res;
> +}

Is there a way that we can make that code common? I guess there could be a
file in arch/powerpc/sysdev that can handle this correctly for all hardware
that requires this particular workaround (currently celleb and QS20, but
potentially more).

	Arnd <><

  reply	other threads:[~2007-09-26 12:20 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-26  4:40 [PATCH 7/7] Celleb: update for PCI Ishizaki Kou
2007-09-26 12:09 ` Arnd Bergmann [this message]
2007-09-27  8:25   ` Benjamin Herrenschmidt
2007-10-02  8:04   ` Ishizaki Kou
2007-10-02  8:18     ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200709261409.32231.arnd@arndb.de \
    --to=arnd@arndb.de \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.