From: Jesper Juhl <jesper.juhl@gmail.com>
To: dmitry pervushin <dpervushin@gmail.com>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
spi-devel-general@lists.sourceforge.net
Subject: Re: SPI
Date: Mon, 26 Sep 2005 22:25:25 +0200 [thread overview]
Message-ID: <200509262225.25946.jesper.juhl@gmail.com> (raw)
In-Reply-To: <1127733134.7577.0.camel@diimka.dev.rtsoft.ru>
On Monday 26 September 2005 13:12, dmitry pervushin wrote:
> Hello guys,
>
> I am attaching the next incarnation of SPI core; feel free to comment it.
>
A few small style comments below.
General notes:
Please use only tabs for indentation.
Please get rid of all the trailing whitespace. A small sed script
like this will do: sed -r s/"[ \t]+$"/""/
Please use only one statement pr line.
Please get rid of the extra whitespace after opening paren and before
closing paren: not like ( this ), but like (this).
Please use a single space after if. Like this: if (foo), not if(foo).
For pointer variables, "type *name" is usually prefered,
not "type* name" or "type * name".
See the changes I've made below for more details (note: I may have missed some
bits, if so, please correct what I missed as well) :-)
See Documentation/CodingStyle for yet more details and rationale.
[snip]
> + */
> +static int spi_bus_match_name(struct device *dev, struct device_driver *drv)
> +{
> + return !strcmp (drv->name, SPI_DEV_CHAR) ||
return !strcmp(drv->name, SPI_DEV_CHAR) ||
[snip]
> + * Parameters:
> + * struct device* dev the 'bus' device
> + * void* context not used. Will be NULL
* struct device *dev the 'bus' device
* void *context not used. Will be NULL
[snip]
> +int __spi_bus_free(struct device *dev, void *context)
> +{
> + struct spi_bus_data *pd = dev->platform_data;
> +
> + atomic_inc(&pd->exiting);
> + kthread_stop(pd->thread);
> + kfree(pd);
> +
> + dev_dbg( dev, "unregistering children\n" );
dev_dbg(dev, "unregistering children\n");
> + /*
> + * NOTE: the loop below might needs redesign. Currently
> + * we delete devices from the head of children list
> + * until the list is empty; that's because the function
> + * device_for_each_child will hold the semaphore needed
> + * for deletion of device
> + */
> + while( !list_empty( &dev->children ) ) {
> + struct device* child = list_entry ( dev->children.next, struct device, node );
> + spi_device_del (TO_SPI_DEV (child) );
while(!list_empty(&dev->children)) {
struct device *child = list_entry(dev->children.next, struct device, node);
spi_device_del(TO_SPI_DEV(child));
[snip]
> + * spi_bus_driver_unregister
> + *
> + * unregisters the SPI bus from the system. Before unregistering, it deletes
> + * each SPI device on the bus using call to __spi_device_free
> + *
> + * Parameters:
> + * struct spi_bus_driver* bus_driver the bus driver
* struct spi_bus_driver *bus_driver the bus driver
[snip]
> +void spi_bus_driver_unregister(struct spi_bus_driver *bus_driver)
> +{
> + if (bus_driver) {
> + driver_for_each_dev( &bus_driver->driver, NULL, __spi_bus_free);
driver_for_each_dev(&bus_driver->driver, NULL, __spi_bus_free);
[snip]
> + * struct device* dev
* struct device *dev
> + * Return value:
> + * none
> + */
> +void spi_device_release( struct device* dev )
void spi_device_release(struct device *dev)
[snip]
> + * struct device* parent the 'bus' device
> + * struct spi_device* dev new device to be added
> + * char* name name of device. Should not be NULL
* struct device *parent the 'bus' device
* struct spi_device *dev new device to be added
* char *name name of device. Should not be NULL
[snip]
> +int spi_device_add(struct device *parent, struct spi_device *dev, char *name)
> +{
> + if (!name || !dev)
> + return -EINVAL;
> +
> + memset(&dev->dev, 0, sizeof(dev->dev));
> + dev->dev.parent = parent;
> + dev->dev.bus = &spi_bus;
> + strncpy( dev->name, name, sizeof(dev->name));
> + strncpy( dev->dev.bus_id, name, sizeof( dev->dev.bus_id ) );
strncpy(dev->dev.bus_id, name, sizeof(dev->dev.bus_id));
[snip]
> + * spi_queue
> + *
> + * Queue the message to be processed asynchronously
> + *
> + * Parameters:
> + * struct spi_msg* msg message to be sent
* struct spi_msg *msg message to be sent
> + * Return value:
> + * 0 on no errors, negative error code otherwise
> + */
> +int spi_queue( struct spi_msg *msg)
int spi_queue(struct spi_msg *msg)
> +{
> + struct device* dev = &msg->device->dev;
struct device *dev = &msg->device->dev;
> + struct spi_bus_data *pd = dev->parent->platform_data;
> +
> + down(&pd->lock);
> + list_add_tail(&msg->link, &pd->msgs);
> + dev_dbg(dev->parent, "message has been queued\n" );
dev_dbg(dev->parent, "message has been queued\n");
[snip]
> + * __spi_transfer_callback
> + *
> + * callback for synchronously processed message. If spi_transfer determines
> + * that there is no callback provided neither by msg->status nor callback
> + * parameter, the __spi_transfer_callback will be used, and spi_transfer
> + * does not return until transfer is finished
> + *
> + * Parameters:
> + * struct spimsg* msg message that is being processed now
* struct spimsg *msg message that is being processed now
> + * int code status of processing
> + */
> +static void __spi_transfer_callback( struct spi_msg* msg, int code )
static void __spi_transfer_callback(struct spi_msg *msg, int code)
> +{
> + if( code & (SPIMSG_OK|SPIMSG_FAILED) )
> + complete( (struct completion*)msg->context );
if (code & (SPIMSG_OK|SPIMSG_FAILED))
complete((struct completion*)msg->context);
[snip]
> + * spi_transfer
> + *
> + * Process the SPI message, by queuing it to the driver and either
> + * immediately return or waiting till the end-of-processing
> + *
> + * Parameters:
> + * struct spi_msg* msg message to process
* struct spi_msg *msg message to process
[snip]
> +int spi_transfer( struct spi_msg* msg, void (*callback)( struct spi_msg*, int ) )
int spi_transfer(struct spi_msg *msg, void (*callback)(struct spi_msg*, int))
> +{
> + struct completion msg_done;
> + int err = -EINVAL;
> +
> + if( callback && !msg->status ) {
if (callback && !msg->status) {
[snip]
> + if( !callback ) {
> + if( !msg->status ) {
> + init_completion( &msg_done );
> + msg->context = &msg_done;
> + msg->status = __spi_transfer_callback;
> + spi_queue( msg );
> + wait_for_completion( &msg_done );
> + err = 0;
> + } else {
> + err = spi_queue( msg );
if (!callback) {
if (!msg->status) {
init_completion(&msg_done);
msg->context = &msg_done;
msg->status = __spi_transfer_callback;
spi_queue(msg);
wait_for_completion(&msg_done);
err = 0;
} else {
err = spi_queue(msg);
[snip]
> + * spi_thread
> + *
> + * This function is started as separate thread to perform actual
> + * transfers on SPI bus
> + *
> + * Parameters:
> + * void* context pointer to struct spi_bus_data
* void *context pointer to struct spi_bus_data
[snip]
> + while (!kthread_should_stop()) {
> +
^^^^^ superfluous blank line.
> + wait_event_interruptible(bd->queue, spi_thread_awake(bd));
[snip]
> + if( bd->bus->set_clock && msg->clock )
> + bd->bus->set_clock(
> + msg->device->dev.parent, msg->clock );
> + xfer_status = bd->bus->xfer( msg );
if (bd->bus->set_clock && msg->clock)
bd->bus->set_clock( <-- this line has trailing whitespace.
msg->device->dev.parent, msg->clock);
xfer_status = bd->bus->xfer(msg);
[snip]
> + * spi_write
> + * send data to a device on an SPI bus
> + * Parameters:
> + * spi_device* dev the target device
> + * char* buf buffer to be sent
* spi_device *dev the target device
* char *buf buffer to be sent
[snip]
> + ret = spi_transfer( msg, NULL );
ret = spi_transfer(msg, NULL);
[snip]
> + * spi_write
> + * receive data from a device on an SPI bus
> + * Parameters:
> + * spi_device* dev the target device
> + * char* buf buffer to be sent
* spi_device *dev the target device
* char *buf buffer to be sent
[snip]
> +int spi_read(struct spi_device *dev, char *buf, int len)
> +{
> + int ret;
> + struct spimsg *msg = spimsg_alloc(dev, SPI_M_RD, len, NULL);
> +
> + ret = spi_transfer( msg, NULL );
ret = spi_transfer(msg, NULL);
[snip]
> +int spi_bus_populate(struct device *parent,
> + char *devices,
> + void (*callback) (struct device * bus,
> + struct spi_device * new_dev))
int spi_bus_populate(struct device *parent,
char *devices,
void (*callback)(struct device *bus,
struct spi_device *new_dev))
[snip]
> + while (devices[0]) {
> + dev_dbg(parent, "discovered new SPI device, name '%s'\n",
> + devices);
> + new_device = kmalloc(sizeof(struct spi_device), GFP_KERNEL);
> + if (!new_device) {
> + break;
> + }
> + if (spi_device_add(parent, new_device, devices)) {
> + break;
> + }
> + if (callback) {
> + callback(parent, new_device);
> + }
if (!new_device)
break;
if (spi_device_add(parent, new_device, devices))
break;
if (callback)
callback(parent, new_device);
We usually don't use curly braces for if statements when the body of the if
is only a single statement.
[snip]
> +int __init spi_core_init( void )
int __init spi_core_init(void)
[snip]
> +++ linux-2.6.10/drivers/spi/spi-dev.c
[snip]
[snip]
> +#include <linux/init.h>
> +#include <asm/uaccess.h>
> +#include <linux/spi.h>
#include <linux/init.h>
#include <linux/spi.h>
#include <asm/uaccess.h>
conventionally, asm/ includes are placed last.
[snip]
> +static ssize_t spidev_read(struct file *file, char *buf, size_t count,
> + loff_t * offset);
> +static ssize_t spidev_write(struct file *file, const char *buf, size_t count,
> + loff_t * offset);
static ssize_t spidev_read(struct file *file, char *buf, size_t count,
loff_t *offset);
static ssize_t spidev_write(struct file *file, const char *buf, size_t count,
loff_t *offset);
[snip]
> +static int spidev_probe(struct device *dev)
> +{
> + struct spidev_driver_data *drvdata;
> +
> + drvdata = kmalloc(sizeof(struct spidev_driver_data), GFP_KERNEL);
> + if ( !drvdata) {
> + dev_dbg( dev, "allocating drvdata failed\n" );
if (!drvdata) {
dev_dbg(dev, "allocating drvdata failed\n");
[snip]
> + dev_dbg( dev, " added\n" );
dev_dbg(dev, " added\n");
[snip]
> +static int spidev_remove(struct device *dev)
> +{
> + struct spidev_driver_data *drvdata;
> +
> + drvdata = (struct spidev_driver_data *)dev_get_drvdata(dev);
> + class_simple_device_remove(MKDEV(SPI_MAJOR, drvdata->minor));
> + kfree(drvdata);
> + dev_dbg( dev, " removed\n" );
dev_dbg(dev, " removed\n");
[snip]
> +static ssize_t spidev_read(struct file *file, char *buf, size_t count,
> + loff_t * offset)
static ssize_t spidev_read(struct file *file, char *buf, size_t count,
loff_t *offset)
> +{
> + struct spi_device *dev = (struct spi_device *)file->private_data;
> + if( count > SPI_TRANSFER_MAX ) count = SPI_TRANSFER_MAX;
> + return spi_read(dev, buf, count );
if (count > SPI_TRANSFER_MAX)
count = SPI_TRANSFER_MAX;
return spi_read(dev, buf, count);
[snip]
> +static ssize_t spidev_write(struct file *file, const char *buf, size_t count,
> + loff_t * offset)
static ssize_t spidev_write(struct file *file, const char *buf, size_t count,
loff_t *offset)
> +{
> + struct spi_device *dev = (struct spi_device *)file->private_data;
> + if( count > SPI_TRANSFER_MAX ) count = SPI_TRANSFER_MAX;
> + return spi_write( dev, buf, count );
if (count > SPI_TRANSFER_MAX)
count = SPI_TRANSFER_MAX;
return spi_write(dev, buf, count);
[snip]
> + if (NULL == drvdata) {
if (drvdata == NULL) {
debatable, but I believe the most common style is what I changed it to.
[snip]
> +++ linux-2.6.10/include/linux/spi.h
[snip]
> +/*
> + * linux/include/linux/spi/spi.h
> + *
> + * Copyright (C) 2005 MontaVista Software, Inc <sources@mvista.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License.
> + *
> + * Derived from l3.h by Jamey Hicks
> + */
+
> +#ifndef SPI_H
Blank line between end of comment and start of code at the top of file seems
to be most common.
[snip]
> +struct spi_bus_data
> +{
> + struct semaphore lock;
> + struct list_head msgs;
> + atomic_t exiting;
> + struct task_struct* thread;
> + wait_queue_head_t queue;
> + struct spi_device* selected_device;
> + struct spi_bus_driver* bus;
struct task_struct *thread;
wait_queue_head_t queue;
struct spi_device *selected_device;
struct spi_bus_driver *bus;
[snip]
> +#define TO_SPI_BUS_DRIVER(drv) container_of( drv, struct spi_bus_driver, driver )
#define TO_SPI_BUS_DRIVER(drv) container_of(drv, struct spi_bus_driver, driver)
> +struct spi_bus_driver
> +{
> + int (*xfer)( struct spi_msg* msg );
> + void (*select)( struct spi_device* dev );
> + void (*deselect)( struct spi_device* dev );
> + void (*set_clock)( struct device* bus_device, u32 clock_hz );
> + struct device_driver driver;
int (*xfer)(struct spi_msg *msg);
void (*select)(struct spi_device *dev);
void (*deselect)(struct spi_device *dev);
void (*set_clock)(struct device *bus_device, u32 clock_hz);
[snip]
> +#define TO_SPI_DEV(device) container_of( device, struct spi_device, dev )
#define TO_SPI_DEV(device) container_of(device, struct spi_device, dev)
> +struct spi_device
> +{
> + char name[ BUS_ID_SIZE ];
char name[BUS_ID_SIZE];
[snip]
> +#define TO_SPI_DRIVER(drv) container_of( drv, struct spi_driver, driver )
#define TO_SPI_DRIVER(drv) container_of(drv, struct spi_driver, driver)
> +struct spi_driver {
> + void* (*alloc)( size_t, int );
> + void (*free)( const void* );
> + unsigned char* (*get_buffer)( struct spi_device*, void* );
> + void (*release_buffer)( struct spi_device*, unsigned char*);
> + void (*control)( struct spi_device*, int mode, u32 ctl );
struct spi_driver {
void *(*alloc)(size_t, int);
void (*free)(const void *);
unsigned char *(*get_buffer)(struct spi_device *, void *);
void (*release_buffer)(struct spi_device *, unsigned char *);
void (*control)(struct spi_device *, int mode, u32 ctl);
[snip]
> +#define SPI_DEV_DRV( device ) TO_SPI_DRIVER( (device)->dev.driver )
#define SPI_DEV_DRV(device) TO_SPI_DRIVER((device)->dev.driver)
> +
> +#define spi_device_lock( dev ) /* down( dev->dev.sem ) */
> +#define spi_device_unlock( dev ) /* up( dev->dev.sem ) */
#define spi_device_lock(dev) /* down(dev->dev.sem) */
#define spi_device_unlock(dev) /* up(dev->dev.sem) */
> +/*
> + * struct spi_msg
> + *
> + * This structure represent the SPI message internally. You should never use fields of this structure directly
> + * Please use corresponding functions to create/destroy/access fields
* This structure represent the SPI message internally.
* You should never use fields of this structure directly.
* Please use corresponding functions to create/destroy/access fields
[snip]
> +struct spi_msg {
> + unsigned char flags;
> +#define SPI_M_RD 0x01
> +#define SPI_M_WR 0x02 /**< Write mode flag */
> +#define SPI_M_CSREL 0x04 /**< CS release level at end of the frame */
> +#define SPI_M_CS 0x08 /**< CS active level at begining of frame ( default low ) */
> +#define SPI_M_CPOL 0x10 /**< Clock polarity */
> +#define SPI_M_CPHA 0x20 /**< Clock Phase */
> + unsigned short len; /* msg length */
> + unsigned long clock;
> + struct spi_device* device;
> + void *context;
> + struct list_head link;
> + void (*status)( struct spi_msg* msg, int code );
#define SPI_M_WR 0x02 /* Write mode flag */
#define SPI_M_CSREL 0x04 /* CS release level at end of the frame */
#define SPI_M_CS 0x08 /* CS active level at begining of frame (default low) */
#define SPI_M_CPOL 0x10 /* Clock polarity */
#define SPI_M_CPHA 0x20 /* Clock Phase */
unsigned short len; /* msg length */
unsigned long clock;
struct spi_device *device;
void *context;
struct list_head link;
void (*status)(struct spi_msg *msg, int code);
[snip]
> +static inline struct spi_msg* spimsg_alloc( struct spi_device* device,
> + unsigned flags,
> + unsigned short len,
> + void (*status)( struct spi_msg*, int code ) )
static inline struct spi_msg* spimsg_alloc( struct spi_device* device,
unsigned flags, unsigned short len,
void (*status)(struct spi_msg *, int code))
> +{
> + struct spi_msg* msg;
> + struct spi_driver* drv = SPI_DEV_DRV( device );
> +
> + msg = kmalloc( sizeof( struct spi_msg ), GFP_KERNEL );
> + if( !msg )
> + return NULL;
> + memset( msg, 0, sizeof( struct spi_msg ) );
struct spi_msg *msg;
struct spi_driver *drv = SPI_DEV_DRV(device);
msg = kmalloc(sizeof(struct spi_msg), GFP_KERNEL);
if (!msg)
return NULL;
memset(msg, 0, sizeof(struct spi_msg));
In addition to the spacing changes you also seem to be using spaces for
indentation here instead of tabs. Please use only tabs for indentation - this
is true for other locations in the file as well, but I'm only mentioning it
once here.
[snip]
> + INIT_LIST_HEAD( &msg->link );
> + if( flags & SPI_M_RD ) {
> + msg->devbuf_rd = drv->alloc ?
> + drv->alloc( len, GFP_KERNEL ):kmalloc( len, GFP_KERNEL);
> + msg->databuf_rd = drv->get_buffer ?
> + drv->get_buffer( device, msg->devbuf_rd ) : msg->devbuf_rd;
> + }
INIT_LIST_HEAD(&msg->link);
if (flags & SPI_M_RD) {
msg->devbuf_rd = drv->alloc ?
drv->alloc(len, GFP_KERNEL) : kmalloc(len, GFP_KERNEL);
msg->databuf_rd = drv->get_buffer ?
drv->get_buffer(device, msg->devbuf_rd) : msg->devbuf_rd;
}
> + if( flags & SPI_M_WR ) {
> + msg->devbuf_wr = drv->alloc ?
> + drv->alloc( len, GFP_KERNEL ):kmalloc( len, GFP_KERNEL);
> + msg->databuf_wr = drv->get_buffer ?
> + drv->get_buffer( device, msg->devbuf_wr ) : msg->devbuf_wr;
> + }
if (flags & SPI_M_WR) {
msg->devbuf_wr = drv->alloc ?
drv->alloc(len, GFP_KERNEL) :
kmalloc(len, GFP_KERNEL);
msg->databuf_wr = drv->get_buffer ?
drv->get_buffer(device, msg->devbuf_wr) :
msg->devbuf_wr;
}
> + pr_debug( "%s: msg = %p, RD=(%p,%p) WR=(%p,%p). Actual flags = %s+%s\n",
> + __FUNCTION__,
> + msg,
> + msg->devbuf_rd, msg->databuf_rd,
> + msg->devbuf_wr, msg->databuf_wr,
> + msg->flags & SPI_M_RD ? "RD" : "~rd",
> + msg->flags & SPI_M_WR ? "WR" : "~wr" );
pr_debug("%s: msg = %p, RD=(%p,%p) WR=(%p,%p). Actual flags = %s+%s\n",
__FUNCTION__,
msg,
msg->devbuf_rd, msg->databuf_rd,
msg->devbuf_wr, msg->databuf_wr,
msg->flags & SPI_M_RD ? "RD" : "~rd",
msg->flags & SPI_M_WR ? "WR" : "~wr");
[snip]
> +static inline void spimsg_free( struct spi_msg * msg )
> +{
> + void (*do_free)( const void* ) = kfree;
> + struct spi_driver* drv = SPI_DEV_DRV( msg->device );
static inline void spimsg_free(struct spi_msg *msg)
{
void (*do_free)(const void *) = kfree;
struct spi_driver *drv = SPI_DEV_DRV(msg->device);
> +
> + if( msg ) {
> + if( drv->free )
> + do_free = drv->free;
> + if( drv->release_buffer ) {
> + if( msg->databuf_rd)
> + drv->release_buffer( msg->device, msg->databuf_rd );
> + if( msg->databuf_wr)
> + drv->release_buffer( msg->device, msg->databuf_wr );
> + }
> + if( msg->devbuf_rd )
> + do_free( msg->devbuf_rd );
> + if( msg->devbuf_wr)
> + do_free( msg->devbuf_wr );
> + kfree( msg );
> + }
if (msg) {
if (drv->free)
do_free = drv->free;
if (drv->release_buffer) {
if (msg->databuf_rd)
drv->release_buffer(msg->device, msg->databuf_rd);
if (msg->databuf_wr)
drv->release_buffer( msg->device, msg->databuf_wr);
}
if (msg->devbuf_rd)
do_free( msg->devbuf_rd);
if (msg->devbuf_wr)
do_free( msg->devbuf_wr);
kfree(msg);
}
[snip]
> +static inline u8* spimsg_buffer_rd( struct spi_msg* msg )
static inline u8 *spimsg_buffer_rd(struct spi_msg *msg)
[snip]
> +static inline u8* spimsg_buffer_wr( struct spi_msg* msg )
static inline u8 *spimsg_buffer_wr(struct spi_msg *msg)
[snip]
> +static inline u8* spimsg_buffer( struct spi_msg* msg )
> +{
> + if( !msg ) return NULL;
> + if( ( msg->flags & (SPI_M_RD|SPI_M_WR) ) == (SPI_M_RD|SPI_M_WR) ) {
> + printk( KERN_ERR"%s: what buffer do you really want ?\n", __FUNCTION__ );
> + return NULL;
> + }
> + if( msg->flags & SPI_M_RD) return msg->databuf_rd;
> + if( msg->flags & SPI_M_WR) return msg->databuf_wr;
> +}
static inline u8 *spimsg_buffer(struct spi_msg* msg)
{
if (!msg)
return NULL;
if ((msg->flags & (SPI_M_RD|SPI_M_WR)) == (SPI_M_RD|SPI_M_WR)) {
printk(KERN_ERR "%s: what buffer do you really want ?\n",
__FUNCTION__ );
return NULL;
}
if (msg->flags & SPI_M_RD)
return msg->databuf_rd;
if (msg->flags & SPI_M_WR)
return msg->databuf_wr;
}
> +
> +#define SPIMSG_OK 0x01
> +#define SPIMSG_FAILED 0x80
> +#define SPIMSG_STARTED 0x02
> +#define SPIMSG_DONE 0x04
> +
> +#define SPI_MAJOR 98
#define SPIMSG_OK 0x01
#define SPIMSG_FAILED 0x80
#define SPIMSG_STARTED 0x02
#define SPIMSG_DONE 0x04
#define SPI_MAJOR 98
It may not be obvious what change I made here, so I'll tell you. You were
mixing spaces and tabs between the defined named and the value, I've changed
it to only use a single tab (it still lines up nicely).
[snip]
> +static inline int spi_bus_driver_register( struct spi_bus_driver* bus_driver )
> +{
> + return driver_register( &bus_driver->driver );
> +}
static inline int spi_bus_driver_register(struct spi_bus_driver *bus_driver)
{
return driver_register(&bus_driver->driver);
}
> +
> +void spi_bus_driver_unregister( struct spi_bus_driver* );
> +int spi_bus_driver_init( struct spi_bus_driver* driver, struct device* dev );
> +int spi_device_add( struct device* parent, struct spi_device*, char* name );
void spi_bus_driver_unregister(struct spi_bus_driver *);
int spi_bus_driver_init(struct spi_bus_driver * driver, struct device *dev);
int spi_device_add(struct device *parent, struct spi_device *, char *name);
> +static inline void spi_device_del( struct spi_device* dev )
> +{
> + device_unregister( &dev->dev );
> +}
static inline void spi_device_del(struct spi_device *dev)
{
device_unregister(&dev->dev);
}
> +static inline int spi_driver_add( struct spi_driver* drv )
> +{
> + return driver_register( &drv->driver );
> +}
static inline int spi_driver_add(struct spi_driver *drv)
{
return driver_register(&drv->driver);
}
> +static inline void spi_driver_del( struct spi_driver* drv )
> +{
> + driver_unregister( &drv->driver );
> +}
static inline void spi_driver_del(struct spi_driver *drv)
{
driver_unregister(&drv->driver);
}
[snip]
> +extern int spi_queue( struct spi_msg* message );
> +extern int spi_transfer( struct spi_msg* message, void (*status)( struct spi_msg*, int ) );
> +extern int spi_bus_populate( struct device* parent, char* device, void (*assign)( struct device* parent, struct spi_device* ) );
extern int spi_queue(struct spi_msg* message);
extern int spi_transfer(struct spi_msg *message,
void (*status)(struct spi_msg *, int));
extern int spi_bus_populate(struct device *parent, char *device,
void (*assign)(struct device *parent, struct spi_device *));
> +
> +#endif /* SPI_H */
#endif /* SPI_H */
--
Jesper Juhl <jesper.juhl@gmail.com>
next prev parent reply other threads:[~2005-09-26 20:23 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-26 11:12 SPI dmitry pervushin
2005-09-26 12:31 ` SPI Eric Piel
2005-09-26 12:37 ` [spi-devel-general] SPI dmitry pervushin
2005-09-26 16:20 ` SPI Grant Likely
2005-09-27 7:39 ` [spi-devel-general] SPI dmitry pervushin
2005-09-26 16:25 ` SPI Valdis.Kletnieks
2005-09-26 16:46 ` [spi-devel-general] SPI Vitaly Wool
2005-09-26 20:25 ` Jesper Juhl [this message]
2005-09-27 12:43 ` SPI Greg KH
2005-09-27 14:27 ` [spi-devel-general] SPI dmitry pervushin
2005-09-27 14:35 ` Greg KH
2005-09-27 14:49 ` dmitry pervushin
2005-09-27 14:54 ` Greg KH
2005-09-27 15:19 ` dmitry pervushin
2005-09-28 13:14 ` [PATCH] SPI dmitry pervushin
-- strict thread matches above, loose matches on Subject: below --
2022-06-09 10:52 SPI Davide Valeri
2022-06-09 11:50 ` SPI Philippe Gerum
2022-06-15 13:53 ` SPI Davide Valeri
2005-11-11 10:11 SPI dmitry pervushin
2005-11-21 20:15 ` SPI Mark Underwood
2005-11-21 20:56 ` SPI Vitaly Wool
2005-11-21 21:23 ` SPI Mark Underwood
2005-11-21 21:27 ` SPI David Brownell
2005-05-31 20:31 SPI Garst R. Reese
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=200509262225.25946.jesper.juhl@gmail.com \
--to=jesper.juhl@gmail.com \
--cc=dpervushin@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=spi-devel-general@lists.sourceforge.net \
/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.