Linux spi驅動分析(二)----SPI核心(bus、device_driver和device)
阿新 • • 發佈:2019-01-31
- struct device {
- struct device *parent;
- struct device_private *p;
- struct kobject kobj;
- const char *init_name; /* initial
name of the device
*/
- const struct device_type
*type;
- struct mutex mutex; /* mutex to synchronize calls to
- *
- */
- struct bus_type *bus; /*
type of bus device is on
*/
- struct device_driver
*driver; /* which driver has allocated
this
- device */
- void *platform_data; /* Platform specific data, device
- core doesn't touch it */
- struct dev_pm_info power;
- struct dev_power_domain *pwr_domain;
- #ifdef CONFIG_NUMA
- int numa_node; /* NUMA node this device is close to */
- #endif
- u64 *dma_mask; /* dma mask (if dma'able device)
*/
- u64 coherent_dma_mask;/* Like dma_mask, but
for
- alloc_coherent mappings as
- not all hardware supports
- 64 bit addresses for consistent
- allocations such descriptors.
*/
- struct device_dma_parameters
*dma_parms;
- struct list_head dma_pools; /* dma pools
(if dma'ble) */
- struct dma_coherent_mem *dma_mem; /* internal for coherent mem
- override */
- /* arch specific additions */
- struct dev_archdata archdata;
- struct device_node *of_node; /* associated device tree node */
- dev_t devt; /* dev_t, creates the sysfs "dev" */
- spinlock_t devres_lock;
- struct list_head devres_head;
- struct klist_node knode_class;
- struct class *class;
- const struct attribute_group **groups; /* optional groups */
- void (*release)(struct device *dev);
- };
- int spi_add_device(struct spi_device *spi)
- {
- static DEFINE_MUTEX(spi_add_lock);
- struct device *dev = spi->master->dev.parent;
- struct device *d;
- int status;
- /* Chipselects are numbered 0..max; validate. */
- if (spi->chip_select >= spi->master->num_chipselect) {
- dev_err(dev, "cs%d >= max %d\n",
- spi->chip_select,
- spi->master->num_chipselect);
- return -EINVAL;
- }
- /* Set the bus ID string */
- dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev),
- spi->chip_select);
- /* We need to make sure there's no other device with
this
- * chipselect
**BEFORE** we
call setup(),
else we'll trash
- * its configuration. Lock against concurrent add() calls.
- */
- mutex_lock(&spi_add_lock);
- d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
- if (d != NULL) {
- dev_err(dev, "chipselect %d already in use\n",
- spi->chip_select);
- put_device(d);
- status = -EBUSY;
- goto done;
- }
- /* Drivers may modify this initial i/o setup, but will
- * normally rely on the device being setup. Devices
- * using SPI_CS_HIGH can't coexist well otherwise...
- */
- status = spi_setup(spi);
- if (status
< 0) {
- dev_err(dev,
"can't setup %s, status %d\n",
- dev_name(&spi->dev), status);
- goto done;
- }
- /* Device may be
bound to an active driver when this returns
*/
- status = device_add(&spi->dev);
- if (status
< 0)
- dev_err(dev,
"can't add %s, status %d\n",
- dev_name(&spi->dev), status);
- else
- dev_dbg(dev,
"registered child %s\n", dev_name(&spi->dev));
- done:
- mutex_unlock(&spi_add_lock);
- return status;
- }