Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0127d6d5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6

* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
  [SPARC64]: Fix args to sun4v_ldc_revoke().
  [SPARC64]: Really fix parport.
  [SPARC64]: Fix IO/MEM space sizing for PCI.
  [SPARC64]: Wire up cookie based sun4v interrupt registry.
parents 1e0e76cf fc395f8d
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -2357,8 +2357,9 @@ sun4v_ldc_unmap:
	 nop
	.size	sun4v_ldc_unmap, .-sun4v_ldc_unmap

	/* %o0:	cookie
	 * %o1:	mte_cookie
	/* %o0: channel
	 * %o1:	cookie
	 * %o2:	mte_cookie
	 *
	 * returns %o0:	status
	 */
+122 −9
Original line number Diff line number Diff line
/* $Id: irq.c,v 1.114 2002/01/11 08:45:38 davem Exp $
 * irq.c: UltraSparc IRQ handling/init/registry.
/* irq.c: UltraSparc IRQ handling/init/registry.
 *
 * Copyright (C) 1997  David S. Miller  (davem@caip.rutgers.edu)
 * Copyright (C) 1997, 2007  David S. Miller  (davem@davemloft.net)
 * Copyright (C) 1998  Eddie C. Dost    (ecd@skynet.be)
 * Copyright (C) 1998  Jakub Jelinek    (jj@ultra.linux.cz)
 */
@@ -43,6 +42,7 @@
#include <asm/cpudata.h>
#include <asm/auxio.h>
#include <asm/head.h>
#include <asm/hypervisor.h>

/* UPA nodes send interrupt packet to UltraSparc with first data reg
 * value low 5 (7 on Starfire) bits holding the IRQ identifier being
@@ -380,6 +380,76 @@ static void sun4v_irq_end(unsigned int virt_irq)
	}
}

static void sun4v_virq_enable(unsigned int virt_irq)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
	unsigned int ino = bucket - &ivector_table[0];

	if (likely(bucket)) {
		unsigned long cpuid, dev_handle, dev_ino;
		int err;

		cpuid = irq_choose_cpu(virt_irq);

		dev_handle = ino & IMAP_IGN;
		dev_ino = ino & IMAP_INO;

		err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
		if (err != HV_EOK)
			printk("sun4v_vintr_set_target(%lx,%lx,%lu): "
			       "err(%d)\n",
			       dev_handle, dev_ino, cpuid, err);
		err = sun4v_vintr_set_state(dev_handle, dev_ino,
					    HV_INTR_ENABLED);
		if (err != HV_EOK)
			printk("sun4v_vintr_set_state(%lx,%lx,"
			       "HV_INTR_ENABLED): err(%d)\n",
			       dev_handle, dev_ino, err);
	}
}

static void sun4v_virq_disable(unsigned int virt_irq)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
	unsigned int ino = bucket - &ivector_table[0];

	if (likely(bucket)) {
		unsigned long dev_handle, dev_ino;
		int err;

		dev_handle = ino & IMAP_IGN;
		dev_ino = ino & IMAP_INO;

		err = sun4v_vintr_set_state(dev_handle, dev_ino,
					    HV_INTR_DISABLED);
		if (err != HV_EOK)
			printk("sun4v_vintr_set_state(%lx,%lx,"
			       "HV_INTR_DISABLED): err(%d)\n",
			       dev_handle, dev_ino, err);
	}
}

static void sun4v_virq_end(unsigned int virt_irq)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
	unsigned int ino = bucket - &ivector_table[0];

	if (likely(bucket)) {
		unsigned long dev_handle, dev_ino;
		int err;

		dev_handle = ino & IMAP_IGN;
		dev_ino = ino & IMAP_INO;

		err = sun4v_vintr_set_state(dev_handle, dev_ino,
					    HV_INTR_STATE_IDLE);
		if (err != HV_EOK)
			printk("sun4v_vintr_set_state(%lx,%lx,"
				"HV_INTR_STATE_IDLE): err(%d)\n",
			       dev_handle, dev_ino, err);
	}
}

static void run_pre_handler(unsigned int virt_irq)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
@@ -434,6 +504,21 @@ static struct irq_chip sun4v_msi = {
};
#endif

static struct irq_chip sun4v_virq = {
	.typename	= "vsun4v",
	.enable		= sun4v_virq_enable,
	.disable	= sun4v_virq_disable,
	.end		= sun4v_virq_end,
};

static struct irq_chip sun4v_virq_ack = {
	.typename	= "vsun4v+ack",
	.enable		= sun4v_virq_enable,
	.disable	= sun4v_virq_disable,
	.ack		= run_pre_handler,
	.end		= sun4v_virq_end,
};

void irq_install_pre_handler(int virt_irq,
			     void (*func)(unsigned int, void *, void *),
			     void *arg1, void *arg2)
@@ -447,7 +532,8 @@ void irq_install_pre_handler(int virt_irq,

	chip = get_irq_chip(virt_irq);
	if (chip == &sun4u_irq_ack ||
	    chip == &sun4v_irq_ack
	    chip == &sun4v_irq_ack ||
	    chip == &sun4v_virq_ack
#ifdef CONFIG_PCI_MSI
	    || chip == &sun4v_msi
#endif
@@ -455,7 +541,9 @@ void irq_install_pre_handler(int virt_irq,
		return;

	chip = (chip == &sun4u_irq ?
		&sun4u_irq_ack : &sun4v_irq_ack);
		&sun4u_irq_ack :
		(chip == &sun4v_irq ?
		 &sun4v_irq_ack : &sun4v_virq_ack));
	set_irq_chip(virt_irq, chip);
}

@@ -492,19 +580,18 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
	return bucket->virt_irq;
}

unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino)
static unsigned int sun4v_build_common(unsigned long sysino,
				       struct irq_chip *chip)
{
	struct ino_bucket *bucket;
	struct irq_handler_data *data;
	unsigned long sysino;

	BUG_ON(tlb_type != hypervisor);

	sysino = sun4v_devino_to_sysino(devhandle, devino);
	bucket = &ivector_table[sysino];
	if (!bucket->virt_irq) {
		bucket->virt_irq = virt_irq_alloc(__irq(bucket));
		set_irq_chip(bucket->virt_irq, &sun4v_irq);
		set_irq_chip(bucket->virt_irq, chip);
	}

	data = get_irq_chip_data(bucket->virt_irq);
@@ -529,6 +616,32 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino)
	return bucket->virt_irq;
}

unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino)
{
	unsigned long sysino = sun4v_devino_to_sysino(devhandle, devino);

	return sun4v_build_common(sysino, &sun4v_irq);
}

unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
{
	unsigned long sysino, hv_err;

	BUG_ON(devhandle & ~IMAP_IGN);
	BUG_ON(devino & ~IMAP_INO);

	sysino = devhandle | devino;

	hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino);
	if (hv_err) {
		prom_printf("IRQ: Fatal, cannot set cookie for [%x:%x] "
			    "err=%lu\n", devhandle, devino, hv_err);
		prom_halt();
	}

	return sun4v_build_common(sysino, &sun4v_virq);
}

#ifdef CONFIG_PCI_MSI
unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p,
			     unsigned int msi_start, unsigned int msi_end)
+9 −3
Original line number Diff line number Diff line
@@ -291,8 +291,9 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)

	for (i = 0; i < num_pbm_ranges; i++) {
		const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
		unsigned long a;
		unsigned long a, size;
		u32 parent_phys_hi, parent_phys_lo;
		u32 size_hi, size_lo;
		int type;

		parent_phys_hi = pr->parent_phys_hi;
@@ -300,9 +301,14 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
		if (tlb_type == hypervisor)
			parent_phys_hi &= 0x0fffffff;

		size_hi = pr->size_hi;
		size_lo = pr->size_lo;

		type = (pr->child_phys_hi >> 24) & 0x3;
		a = (((unsigned long)parent_phys_hi << 32UL) |
		     ((unsigned long)parent_phys_lo  <<  0UL));
		size = (((unsigned long)size_hi << 32UL) |
			((unsigned long)size_lo  <<  0UL));

		switch (type) {
		case 0:
@@ -313,7 +319,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
		case 1:
			/* 16-bit IO space, 16MB */
			pbm->io_space.start = a;
			pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL);
			pbm->io_space.end = a + size - 1UL;
			pbm->io_space.flags = IORESOURCE_IO;
			saw_io = 1;
			break;
@@ -321,7 +327,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
		case 2:
			/* 32-bit MEM space, 2GB */
			pbm->mem_space.start = a;
			pbm->mem_space.end = a + (0x80000000UL - 1UL);
			pbm->mem_space.end = a + size - 1UL;
			pbm->mem_space.flags = IORESOURCE_MEM;
			saw_mem = 1;
			break;
+14 −28
Original line number Diff line number Diff line
@@ -15,8 +15,7 @@
static inline int
dma_supported(struct device *dev, u64 mask)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	return pci_dma_supported(to_pci_dev(dev), mask);
}
@@ -24,8 +23,7 @@ dma_supported(struct device *dev, u64 mask)
static inline int
dma_set_mask(struct device *dev, u64 dma_mask)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
}
@@ -34,8 +32,7 @@ static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
		   gfp_t flag)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	return pci_iommu_ops->alloc_consistent(to_pci_dev(dev), size, dma_handle, flag);
}
@@ -44,8 +41,7 @@ static inline void
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
		    dma_addr_t dma_handle)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
}
@@ -54,8 +50,7 @@ static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
	       enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction);
}
@@ -64,8 +59,7 @@ static inline void
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
		 enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction);
}
@@ -75,8 +69,7 @@ dma_map_page(struct device *dev, struct page *page,
	     unsigned long offset, size_t size,
	     enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	return pci_map_page(to_pci_dev(dev), page, offset, size, (int)direction);
}
@@ -85,8 +78,7 @@ static inline void
dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
	       enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction);
}
@@ -95,8 +87,7 @@ static inline int
dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
	   enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
}
@@ -105,8 +96,7 @@ static inline void
dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
	     enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction);
}
@@ -115,8 +105,7 @@ static inline void
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
			enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle,
				    size, (int)direction);
@@ -126,8 +115,7 @@ static inline void
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
			   enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle,
				       size, (int)direction);
@@ -137,8 +125,7 @@ static inline void
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
		    enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, nelems, (int)direction);
}
@@ -147,8 +134,7 @@ static inline void
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
		       enum dma_data_direction direction)
{
	BUG_ON(dev->bus != &pci_bus_type &&
	       dev->bus != &ebus_bus_type);
	BUG_ON(dev->bus != &pci_bus_type);

	pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, nelems, (int)direction);
}
+5 −3
Original line number Diff line number Diff line
@@ -2615,8 +2615,9 @@ struct ldc_mtable_entry {
/* ldc_revoke()
 * TRAP:	HV_FAST_TRAP
 * FUNCTION:	HV_FAST_LDC_REVOKE
 * ARG0:	cookie
 * ARG1:	ldc_mtable_entry cookie
 * ARG0:	channel ID
 * ARG1:	cookie
 * ARG2:	ldc_mtable_entry cookie
 * RET0:	status
 */
#define HV_FAST_LDC_REVOKE		0xef
@@ -2663,7 +2664,8 @@ extern unsigned long sun4v_ldc_mapin(unsigned long channel,
				     unsigned long *ra,
				     unsigned long *perm);
extern unsigned long sun4v_ldc_unmap(unsigned long ra);
extern unsigned long sun4v_ldc_revoke(unsigned long cookie,
extern unsigned long sun4v_ldc_revoke(unsigned long channel,
				      unsigned long cookie,
				      unsigned long mte_cookie);
#endif

Loading