Reputation: 7431
I want to make the platform driver I'm writing reentrant: where do I store memory dynamically assigned during the probe and/or open calls (int probe(struct platform_device*)
/int open(struct inode *inode, struct file *)
)
The driver can be instantiated on multiple pieces of in-system hardware, with each of them being accessed concurrently from user space.
Can I use the private_data
field from struct file and the platform_data
from struct device as arbitrary pointers to allocated memory?
Upvotes: 0
Views: 457
Reputation: 36
If you are writing a platform driver, you should use dev_set_drvdata()
function, which sets the driver_data
field in struct device
, .
There is an example.
struct blink_local {
int irq;
unsigned long mem_start;
unsigned long mem_end;
void __iomem *base_addr;
};
static int blink_probe(struct platform_device *pdev)
{
struct resource *r_irq; /* Interrupt resources */
struct resource *r_mem; /* IO mem resources */
struct device *dev = &pdev->dev;
struct blink_local *lp = NULL;
int rc = 0;
dev_info(dev, "Device Tree Probing\n");
/* Get iospace for the device */
r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r_mem) {
dev_err(dev, "invalid address\n");
return -ENODEV;
}
lp = (struct blink_local *) kmalloc(sizeof(struct blink_local), GFP_KERNEL);
if (!lp) {
dev_err(dev, "Cound not allocate blink device\n");
return -ENOMEM;
}
dev_set_drvdata(dev, lp);
lp->mem_start = r_mem->start;
lp->mem_end = r_mem->end;
if (!request_mem_region(lp->mem_start,
lp->mem_end - lp->mem_start + 1,
DRIVER_NAME)) {
dev_err(dev, "Couldn't lock memory region at %p\n",
(void *)lp->mem_start);
rc = -EBUSY;
goto error1;
}
lp->base_addr = ioremap(lp->mem_start, lp->mem_end - lp->mem_start + 1);
if (!lp->base_addr) {
dev_err(dev, "blink: Could not allocate iomem\n");
rc = -EIO;
goto error2;
}
/* Get IRQ for the device */
r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!r_irq) {
dev_info(dev, "no IRQ found\n");
dev_info(dev, "blink at 0x%08x mapped to 0x%08x\n",
(unsigned int __force)lp->mem_start,
(unsigned int __force)lp->base_addr);
return 0;
}
lp->irq = r_irq->start;
rc = request_irq(lp->irq, &blink_irq, 0, DRIVER_NAME, lp);
if (rc) {
dev_err(dev, "testmodule: Could not allocate interrupt %d.\n",
lp->irq);
goto error3;
}
return 0;
error3:
free_irq(lp->irq, lp);
error2:
release_mem_region(lp->mem_start, lp->mem_end - lp->mem_start + 1);
error1:
kfree(lp);
dev_set_drvdata(dev, NULL);
return rc;
}
Upvotes: 2
Reputation: 4215
For memory allocated dynamically by the driver, the private_data
field of struct file
is the one to use.
The way this field is used is up to the driver, the kernel doesn't touch it. It's there just for the drivers to use.
You can also have a look at this previous question.
Upvotes: 0