Changeset 3469

Show
Ignore:
Timestamp:
04/18/00 10:48:56 (13 years ago)
Author:
simon
Message:

(simon) Merged Juha Valkama's code: get a client based on driver and adapter

id, and be able to lock/release it -> usage_count. See his mail for
a detailed description.

Location:
i2c/trunk/kernel
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • i2c/trunk/kernel/i2c-core.c

    r3453 r3469  
    380380        DEB(printk("i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n", 
    381381                client->name, adapter->name,i)); 
     382 
     383        if(client->flags & I2C_CLIENT_ALLOW_USE) 
     384                client->usage_count = 0; 
     385         
    382386        return 0; 
    383387} 
     
    397401                return -ENODEV; 
    398402        } 
    399  
     403         
     404        if( (client->flags & I2C_CLIENT_ALLOW_USE) &&  
     405            (client->usage_count>0)) 
     406                return -EBUSY; 
     407         
    400408        if (adapter->client_unregister != NULL)  
    401409                adapter->client_unregister(client); 
     
    422430void i2c_dec_use_client(struct i2c_client *client) 
    423431{ 
    424  
     432         
    425433        if (client->driver->dec_use != NULL) 
    426434                client->driver->dec_use(client); 
     
    428436        if (client->adapter->dec_use != NULL) 
    429437                client->adapter->dec_use(client->adapter); 
     438} 
     439 
     440struct i2c_client *i2c_get_client(int driver_id, int adapter_id,  
     441                                        struct i2c_client *prev) 
     442{ 
     443        int i,j; 
     444        struct i2c_adapter *adapter=0; 
     445         
     446        /* Will iterate through the list of clients in each adapter of adapters-list 
     447           in search for a client that matches the search criteria. driver_id or  
     448           adapter_id are ignored if set to 0. If both are ignored this returns  
     449           first client found. */ 
     450         
     451        i = j = 0;   
     452         
     453        /* set starting point */  
     454        if(prev) 
     455        { 
     456                if(!(prev->adapter)) 
     457                        return (struct i2c_client *) -EINVAL; 
     458                 
     459                for(j=0; j < I2C_ADAP_MAX; j++) 
     460                        if(prev->adapter == adapters[j]) 
     461                                break; 
     462                 
     463                /* invalid starting point? */ 
     464                if (I2C_ADAP_MAX == j) { 
     465                        printk(KERN_WARNING " i2c-core.o: get_client adapter for client:[%s] not found\n", 
     466                                prev->name); 
     467                        return (struct i2c_client *) -ENODEV; 
     468                }        
     469                 
     470                for(i=0; i < I2C_CLIENT_MAX; i++) 
     471                        if(prev == adapters[j]->clients[i]) 
     472                                break; 
     473                 
     474                /* invalid starting point? */ 
     475                if (I2C_CLIENT_MAX == i) { 
     476                        printk(KERN_WARNING " i2c-core.o: get_client client:[%s] not found\n", 
     477                                prev->name); 
     478                        return (struct i2c_client *) -ENODEV; 
     479                }        
     480                 
     481                i++; /* start from one after prev */ 
     482        } 
     483         
     484        for(; j < I2C_ADAP_MAX; j++) 
     485        { 
     486                if(!adapters[j]) 
     487                        continue; 
     488                         
     489                if(adapter_id && (adapters[j]->id != adapter_id)) 
     490                        continue; 
     491                 
     492                for(; i < I2C_CLIENT_MAX; i++) 
     493                { 
     494                        if(!adapters[j]->clients[i]) 
     495                                continue; 
     496                                 
     497                        if(driver_id && (adapters[j]->clients[i]->driver->id != driver_id)) 
     498                                continue; 
     499                        if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE)        
     500                                return adapters[j]->clients[i]; 
     501                } 
     502        } 
     503 
     504        return 0; 
     505} 
     506 
     507int i2c_use_client(struct i2c_client *client) 
     508{ 
     509        if(client->flags & I2C_CLIENT_ALLOW_USE) 
     510                if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)  
     511                        client->usage_count++; 
     512                else 
     513                        if(client->usage_count > 0) 
     514                                return -EBUSY; 
     515                        else 
     516                                client->usage_count++; 
     517 
     518        i2c_inc_use_client(client); 
     519 
     520        return 0; 
     521} 
     522 
     523int i2c_release_client(struct i2c_client *client) 
     524{ 
     525        if(client->flags & I2C_CLIENT_ALLOW_USE) 
     526                if(client->usage_count>0) 
     527                        client->usage_count--; 
     528                else 
     529                { 
     530                        printk(KERN_WARNING " i2c-core.o: dec_use_client used one too many times\n"); 
     531                        return -EPERM; 
     532                } 
     533         
     534        i2c_dec_use_client(client); 
     535         
     536        return 0; 
    430537} 
    431538 
     
    11871294EXPORT_SYMBOL(i2c_inc_use_client); 
    11881295EXPORT_SYMBOL(i2c_dec_use_client); 
     1296EXPORT_SYMBOL(i2c_get_client); 
     1297EXPORT_SYMBOL(i2c_use_client); 
     1298EXPORT_SYMBOL(i2c_release_client); 
    11891299EXPORT_SYMBOL(i2c_check_addr); 
    11901300 
  • i2c/trunk/kernel/i2c.h

    r3450 r3469  
    199199        struct i2c_driver *driver;      /* and our access routines      */ 
    200200        void *data;                     /* for the clients              */ 
     201        int usage_count;                /* How many accesses currently  */ 
     202                                        /* to the client                */ 
    201203}; 
    202204 
     
    284286#define I2C_DF_DUMMY    0x02            /* do not connect any clients */ 
    285287 
     288/*flags for the client struct: */ 
     289#define I2C_CLIENT_ALLOW_USE            0x01    /* Client allows access */ 
     290#define I2C_CLIENT_ALLOW_MULTIPLE_USE   0x02    /* Allow multiple access-locks */ 
     291                                                /* on an i2c_client */ 
     292 
    286293/* i2c_client_address_data is the struct for holding default client 
    287294 * addresses for a driver and for the parameters supplied on the 
     
    326333extern void i2c_inc_use_client(struct i2c_client *); 
    327334extern void i2c_dec_use_client(struct i2c_client *); 
     335 
     336/* New function: This is to get an i2c_client-struct for controlling the  
     337   client either by using i2c_control-function or having the  
     338   client-module export functions that can be used with the i2c_client 
     339   -struct. */ 
     340extern struct i2c_client *i2c_get_client(int driver_id, int adapter_id,  
     341                                        struct i2c_client *prev); 
     342 
     343/* Should be used with new function 
     344   extern struct i2c_client *i2c_get_client(int,int,struct i2c_client *); 
     345   to make sure that client-struct is valid and that it is okay to access 
     346   the i2c-client.  
     347   returns -EACCES if client doesn't allow use (default) 
     348   returns -EBUSY if client doesn't allow multiple use (default) and  
     349   usage_count >0 */ 
     350extern int i2c_use_client(struct i2c_client *); 
     351extern int i2c_release_client(struct i2c_client *); 
    328352 
    329353/* returns -EBUSY if address has been taken, 0 if not. Note that the only