From: Matthias Fechner <idefix@fechner.net>
To: linuxppc-embedded@ozlabs.org
Subject: Re: Problem in compiling a kernel module
Date: Wed, 14 Mar 2007 05:33:05 +0100 [thread overview]
Message-ID: <20070314043305.GB27011@server.idefix.lan> (raw)
In-Reply-To: <513703.69187.qm@web302.biz.mail.mud.yahoo.com>
[-- Attachment #1: Type: text/plain, Size: 683 bytes --]
Hello Ben,
* Ben Warren <bwarren@qstreams.com> [13-03-07 05:55]:
> Is there any chance that you qualify private data as
> __init within the driver? Can you post the cleanup()
> function and any private (static) functions that it
> calls?
no problem, I attached the file. It is bery basic from now and it is
not written very well, but it should have all necessary parts in it.
PS: It's not necessary to CC me I'm on the list :)
Best regards,
Matthias
--
"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the universe trying to
produce bigger and better idiots. So far, the universe is winning." --
Rich Cook
[-- Attachment #2: max6633.c --]
[-- Type: text/x-csrc, Size: 5720 bytes --]
/*
driver to support MAX6633
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#define MAX6633_VERSION 0.1
#define MAX6633_DATE 20070301
//#define MAX633_SYSCTL_FUNC1 0x1000
//#define MAX6633_REG_GENERIX 0x0
int max6633_attach_adapter(struct i2c_adapter *adapter);
int max6633_detach_client(struct i2c_client *client);
int max6633_detect_client(struct i2c_adapter *adapter, int address, int kind);
void max6633_cleanup(void);
static struct i2c_driver max6633_driver = {
.driver = {
.name = "max6633",
},
.attach_adapter = max6633_attach_adapter,
.detach_client = max6633_detach_client,
// .command = &max6633_command /* may be NULL */
};
struct max6633_data
{
struct i2c_client client;
struct mutex update_lock;
int sysctl_id; /* To keep the /proc directory entry */
char valid;
u16 temp;
unsigned long last_updated;
};
/// TODO: create the function func1 or rename it here
/*
static ctl_table max6633_dir_table_template[]= {
{ MAX633_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &max6633_temp },
{ 0 }
};
*/
void max6633_temp(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
return;
}
int max6633_read_value(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_word_data(client,reg);
}
int max6633_write_value(struct i2c_client *client, u8 reg, u16 value)
{
return i2c_smbus_write_word_data(client,reg,value);
}
/// TODO: check all possible addresses
/* scan 0x40, 0x41 and 0x42 */
static unsigned short normal_i2c[] = {
0x40, 0x41, 0x42, I2C_CLIENT_END
};
/* Magic definition of all other variables and things */
I2C_CLIENT_INSMOD;
int max6633_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_probe(adapter, &addr_data,max6633_detect_client);
}
int max6633_detect_client(struct i2c_adapter *adapter, int address, int kind)
{
int err=0;
//int i;
struct i2c_client *new_client;
struct max6633_data *data;
/* Let's see wheter this adapter can support what we need */
if(!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BYTE_DATA))
{
printk("max6633: Adapter doesn't support functionality.\n");
goto ERROR0;
}
// const char *type_name="";
/* OK. For now, we presume we have a valid client. We no create the
client structure, even though we cannot fill it completely yet.
But it allows us to access several i2c functions safely */
if(!(data=kzalloc(sizeof(struct max6633_data), GFP_KERNEL)))
{
err=-ENOMEM;
goto ERROR0;
}
new_client=&data->client;
i2c_set_clientdata(new_client, data);
new_client->addr=address;
new_client->adapter=adapter;
new_client->driver=&max6633_driver;
new_client->flags=0;
/* Now, we do the remaining detection. If no `force' parameter is used. */
/* First, the generic detection (if any), that is skipped if any force
parameter was used. */
if(kind <0)
{
/* The bellow is of course bogus */
/*
if(max6633_read_value(new_client, MAX633_REG_GENERIC) != MAX633_GENERIC_VALUE)
goto ERROR1;
*/
}
/* Fill in the remaining client fields. */
strcpy(new_client->name,"max6633");
data->valid=0;
//init_MUTEX(&data->update_lock); /* only if you use this field */
/* Any other initialisation in data must be done here too. */
/* Tell the i2c layer a new client has arrived */
if((err=i2c_attach_client(new_client)))
goto ERROR3;
// type_name="chip1"; /* for /proc entry */
/* Register a new directory entry with module sensors. See above for
the template structure. */
/* if((i=i2c_register_entry(new_client, type_name,
max6633_dir_table_template, THIS_MODULE)) < 0)
{
err=i;
goto ERROR4;
}
*/
//data->sysctl_id=i;
/* This function can write default values to the client registers, if
needed. */
//max6633_init_client(new_client);
printk(KERN_INFO "Found max6633 I2C temperature sensor.\n");
return 0;
/* OK, this is not exactly good programming practice, usually. But it is
ver code-efficient in this case. */
// ERROR4:
// i2c_detach_client(new_client);
ERROR3:
// ERROR2:
// ERROR1:
kfree(data);
ERROR0:
return err;
}
int max6633_detach_client(struct i2c_client *client)
{
int err;
/* Try to detach the client from i2c space */
if((err=i2c_detach_client(client)))
return err;
kfree(i2c_get_clientdata(client));
return 0;
}
/* Keep track of how far we got in the initialisation process. If several
things have to initialized and we fail halfway, only those things
have to be cleared up! */
static int __initdata max6633_initialized = 0;
static int __init max6633_init(void)
{
int res;
printk("max6633 version %f (%d)\n", MAX6633_VERSION, MAX6633_DATE);
if((res=i2c_add_driver(&max6633_driver)))
{
printk("max6633: Driver registration failed, module not inserted.\n");
max6633_cleanup();
return res;
}
max6633_initialized ++;
return 0;
}
void max6633_cleanup(void)
{
int res;
if(max6633_initialized==1)
{
if((res=i2c_del_driver(&max6633_driver)))
{
printk("max6633: Driver registration failed, module not removed.\n");
return;
}
max6633_initialized --;
}
}
MODULE_AUTHOR("Matthias Fechner <idefix@fechner.net>");
MODULE_DESCRIPTION("Driver for MAX6633 temperature I2C device.");
module_init(max6633_init);
module_exit(max6633_cleanup);
next prev parent reply other threads:[~2007-03-14 4:33 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-12 17:00 Problem in compiling a kernel module Matthias Fechner
2007-03-12 18:36 ` Grant Likely
2007-03-13 4:30 ` Matthias Fechner
2007-03-13 4:55 ` Grant Likely
2007-03-13 12:55 ` Ben Warren
2007-03-14 4:33 ` Matthias Fechner [this message]
2007-03-14 6:54 ` Domen Puncer
2007-03-15 4:27 ` Matthias Fechner
2007-08-07 17:42 ` Fedora 7 on a non FPU system Michael Brian Willis
2007-08-07 19:11 ` Roland Dreier
2007-08-07 19:29 ` Josh Boyer
2007-08-07 21:43 ` Clemens Koller
2007-08-08 22:18 ` Michael Brian Willis
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=20070314043305.GB27011@server.idefix.lan \
--to=idefix@fechner.net \
--cc=linuxppc-embedded@ozlabs.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).