soc: ixp4xx: qmgr: Pass resources
Instead of using hardcoded base address implicitly obtained through <linux/io.h>, pass the physical base for the QMGR block as a memory resource and remap it in the driver. Also pass the two IRQs as resources and obtain them in the driver. Use devm_* accessors and simplify the error path in the process. Drop memory region request as this is done by the devm_ioremap* functions. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
6b39031954
commit
ecc133c6da
@ -66,11 +66,6 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
|
|||||||
.pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
|
.pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
|
||||||
.length = IXP4XX_PCI_CFG_REGION_SIZE,
|
.length = IXP4XX_PCI_CFG_REGION_SIZE,
|
||||||
.type = MT_DEVICE
|
.type = MT_DEVICE
|
||||||
}, { /* Queue Manager */
|
|
||||||
.virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT,
|
|
||||||
.pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS),
|
|
||||||
.length = IXP4XX_QMGR_REGION_SIZE,
|
|
||||||
.type = MT_DEVICE
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -176,9 +171,29 @@ static struct platform_device ixp4xx_npe_device = {
|
|||||||
.resource = ixp4xx_npe_resources,
|
.resource = ixp4xx_npe_resources,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct resource ixp4xx_qmgr_resources[] = {
|
||||||
|
{
|
||||||
|
.start = IXP4XX_QMGR_BASE_PHYS,
|
||||||
|
.end = IXP4XX_QMGR_BASE_PHYS + 0x3fff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = IRQ_IXP4XX_QM1,
|
||||||
|
.end = IRQ_IXP4XX_QM1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = IRQ_IXP4XX_QM2,
|
||||||
|
.end = IRQ_IXP4XX_QM2,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device ixp4xx_qmgr_device = {
|
static struct platform_device ixp4xx_qmgr_device = {
|
||||||
.name = "ixp4xx-qmgr",
|
.name = "ixp4xx-qmgr",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
|
.num_resources = ARRAY_SIZE(ixp4xx_qmgr_resources),
|
||||||
|
.resource = ixp4xx_qmgr_resources,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device *ixp4xx_devices[] __initdata = {
|
static struct platform_device *ixp4xx_devices[] __initdata = {
|
||||||
|
@ -43,8 +43,6 @@
|
|||||||
* Queue Manager
|
* Queue Manager
|
||||||
*/
|
*/
|
||||||
#define IXP4XX_QMGR_BASE_PHYS 0x60000000
|
#define IXP4XX_QMGR_BASE_PHYS 0x60000000
|
||||||
#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000)
|
|
||||||
#define IXP4XX_QMGR_REGION_SIZE 0x00004000
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Peripheral space, including debug UART. Must be section-aligned so that
|
* Peripheral space, including debug UART. Must be section-aligned so that
|
||||||
|
@ -16,13 +16,9 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/soc/ixp4xx/qmgr.h>
|
#include <linux/soc/ixp4xx/qmgr.h>
|
||||||
|
|
||||||
/* FIXME: get rid of these static assigments */
|
static struct qmgr_regs __iomem *qmgr_regs;
|
||||||
#define IRQ_IXP4XX_BASE 16
|
static int qmgr_irq_1;
|
||||||
#define IRQ_IXP4XX_QM1 (IRQ_IXP4XX_BASE + 3)
|
static int qmgr_irq_2;
|
||||||
#define IRQ_IXP4XX_QM2 (IRQ_IXP4XX_BASE + 4)
|
|
||||||
|
|
||||||
static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
|
|
||||||
static struct resource *mem_res;
|
|
||||||
static spinlock_t qmgr_lock;
|
static spinlock_t qmgr_lock;
|
||||||
static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
|
static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
|
||||||
static void (*irq_handlers[QUEUES])(void *pdev);
|
static void (*irq_handlers[QUEUES])(void *pdev);
|
||||||
@ -190,7 +186,7 @@ static irqreturn_t qmgr_irq2_a0(int irq, void *pdev)
|
|||||||
|
|
||||||
static irqreturn_t qmgr_irq(int irq, void *pdev)
|
static irqreturn_t qmgr_irq(int irq, void *pdev)
|
||||||
{
|
{
|
||||||
int i, half = (irq == IRQ_IXP4XX_QM1 ? 0 : 1);
|
int i, half = (irq == qmgr_irq_1 ? 0 : 1);
|
||||||
u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]);
|
u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]);
|
||||||
|
|
||||||
if (!req_bitmap)
|
if (!req_bitmap)
|
||||||
@ -381,12 +377,25 @@ static int ixp4xx_qmgr_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
int i, err;
|
int i, err;
|
||||||
irq_handler_t handler1, handler2;
|
irq_handler_t handler1, handler2;
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct resource *res;
|
||||||
|
int irq1, irq2;
|
||||||
|
|
||||||
mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS,
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
IXP4XX_QMGR_REGION_SIZE,
|
if (!res)
|
||||||
"IXP4xx Queue Manager");
|
return -ENODEV;
|
||||||
if (mem_res == NULL)
|
qmgr_regs = devm_ioremap_resource(dev, res);
|
||||||
return -EBUSY;
|
if (!qmgr_regs)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
irq1 = platform_get_irq(pdev, 0);
|
||||||
|
if (irq1 <= 0)
|
||||||
|
return irq1 ? irq1 : -EINVAL;
|
||||||
|
qmgr_irq_1 = irq1;
|
||||||
|
irq2 = platform_get_irq(pdev, 1);
|
||||||
|
if (irq2 <= 0)
|
||||||
|
return irq2 ? irq2 : -EINVAL;
|
||||||
|
qmgr_irq_2 = irq2;
|
||||||
|
|
||||||
/* reset qmgr registers */
|
/* reset qmgr registers */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
@ -411,43 +420,33 @@ static int ixp4xx_qmgr_probe(struct platform_device *pdev)
|
|||||||
} else
|
} else
|
||||||
handler1 = handler2 = qmgr_irq;
|
handler1 = handler2 = qmgr_irq;
|
||||||
|
|
||||||
err = request_irq(IRQ_IXP4XX_QM1, handler1, 0, "IXP4xx Queue Manager",
|
err = devm_request_irq(dev, irq1, handler1, 0, "IXP4xx Queue Manager",
|
||||||
NULL);
|
NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n",
|
dev_err(dev, "failed to request IRQ%i (%i)\n",
|
||||||
IRQ_IXP4XX_QM1, err);
|
irq1, err);
|
||||||
goto error_irq;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = request_irq(IRQ_IXP4XX_QM2, handler2, 0, "IXP4xx Queue Manager",
|
err = devm_request_irq(dev, irq2, handler2, 0, "IXP4xx Queue Manager",
|
||||||
NULL);
|
NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n",
|
dev_err(dev, "failed to request IRQ%i (%i)\n",
|
||||||
IRQ_IXP4XX_QM2, err);
|
irq2, err);
|
||||||
goto error_irq2;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
|
used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
|
||||||
spin_lock_init(&qmgr_lock);
|
spin_lock_init(&qmgr_lock);
|
||||||
|
|
||||||
printk(KERN_INFO "IXP4xx Queue Manager initialized.\n");
|
dev_info(dev, "IXP4xx Queue Manager initialized.\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_irq2:
|
|
||||||
free_irq(IRQ_IXP4XX_QM1, NULL);
|
|
||||||
error_irq:
|
|
||||||
release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ixp4xx_qmgr_remove(struct platform_device *pdev)
|
static int ixp4xx_qmgr_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
free_irq(IRQ_IXP4XX_QM1, NULL);
|
synchronize_irq(qmgr_irq_1);
|
||||||
free_irq(IRQ_IXP4XX_QM2, NULL);
|
synchronize_irq(qmgr_irq_2);
|
||||||
synchronize_irq(IRQ_IXP4XX_QM1);
|
|
||||||
synchronize_irq(IRQ_IXP4XX_QM2);
|
|
||||||
release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user