Commit c658c47a authored by Alessandro Rubini's avatar Alessandro Rubini

general: bugfix for non-probed cards; minor cleanups

parent 16e28a60
......@@ -15,6 +15,7 @@
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/list.h>
......@@ -106,7 +107,7 @@ int fd_reset_again(struct spec_fd *fd)
}
/* This structure lists the various subsystems */
struct modlist {
struct fd_modlist {
char *name;
int (*init)(struct spec_fd *);
void (*exit)(struct spec_fd *);
......@@ -114,7 +115,7 @@ struct modlist {
#define SUBSYS(x) { #x, fd_ ## x ## _init, fd_ ## x ## _exit }
static struct modlist mods[] = {
static struct fd_modlist mods[] = {
SUBSYS(spi),
SUBSYS(gpio),
SUBSYS(pll),
......@@ -130,7 +131,7 @@ static struct modlist mods[] = {
/* probe and remove are called by fd-spec.c */
int fd_probe(struct spec_dev *dev)
{
struct modlist *m;
struct fd_modlist *m;
struct spec_fd *fd;
int i, ret;
......@@ -187,6 +188,7 @@ int fd_probe(struct spec_dev *dev)
ts2.tv_sec, ts2.tv_nsec,
ts3.tv_sec, ts3.tv_nsec);
}
set_bit(FD_FLAG_INITED, &fd->flags);
return 0;
err:
......@@ -198,14 +200,18 @@ err:
void fd_remove(struct spec_dev *dev)
{
struct modlist *m;
struct fd_modlist *m;
struct spec_fd *fd = dev->sub_priv;
int i = ARRAY_SIZE(mods);
if (!test_bit(FD_FLAG_INITED, &fd->flags))
return; /* No init, no exit */
pr_debug("%s\n",__func__);
while (--i >= 0) {
m = mods + i;
if (m->exit)
m->exit(dev->sub_priv);
m->exit(fd);
}
}
......
......@@ -31,7 +31,7 @@ static int fd_is_valid(int bus, int devfn)
int fd_spec_init(void)
{
struct spec_dev *dev;
int ret, retsave = 0, err = 0;
int ret, success = 0, retsave = 0, err = 0;
/* Scan the list and see what is there. Take hold of everything */
list_for_each_entry(dev, &spec_list, list) {
......@@ -44,13 +44,20 @@ int fd_spec_init(void)
if (ret < 0) {
retsave = ret;
err++;
} else {
success++;
}
}
if (err) {
/* FIXME: doesn't undo the other boards */
return retsave;
pr_err("%s: Setup of %i boards failed (%i succeeded)\n",
KBUILD_MODNAME, err, success);
pr_err("%s: last error: %i\n", KBUILD_MODNAME, retsave);
}
return 0;
if (success) {
/* At least one board has been successfully initialized */
return 0;
}
return retsave; /* last error code */
}
void fd_spec_exit(void)
......
......@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/zio.h>
......@@ -132,11 +133,11 @@ static int fd_input(struct zio_cset *cset)
fd = __HACK__FD__;
/* Configure the device for input */
if (!fd->flags & FD_FLAG_INPUT) {
if (!test_bit(FD_FLAG_INPUT, &fd->flags)) {
fd_writel(fd, FD_TSBCR_PURGE | FD_TSBCR_RST_SEQ, FD_REG_TSBCR);
fd_writel(fd, FD_TSBCR_CHAN_MASK_W(1) | FD_TSBCR_ENABLE,
FD_REG_TSBCR);
fd->flags |= FD_FLAG_INPUT;
set_bit(FD_FLAG_INPUT, &fd->flags);
}
return -EAGAIN; /* Will be completed over time */
......
......@@ -50,7 +50,11 @@ struct spec_fd {
int temp; /* temperature: scaled by 4 bits */
int verbose;
};
#define FD_FLAG_INPUT 1 /* temporary: check flags */
/* We act on flags using atomic ops, so flag is the number, not the mask */
enum fd_flags {
FD_FLAG_INITED = 0,
FD_FLAG_INPUT
};
/* Internal time: the first three fields should be converted to zio time */
struct fd_time {
......
......@@ -139,8 +139,11 @@ static int ow_read_block(struct spec_fd *fd, int port, uint8_t *block, int len)
static int ds18x_read_serial(struct spec_fd *fd)
{
if(!ow_reset(fd, 0))
if(!ow_reset(fd, 0)) {
pr_err("%s: Failure in resetting one-wire channel\n",
KBUILD_MODNAME);
return -EIO;
}
ow_write_byte(fd, FD_OW_PORT, CMD_ROM_READ);
return ow_read_block(fd, FD_OW_PORT, fd->ds18_id, 8);
......@@ -149,17 +152,20 @@ static int ds18x_read_serial(struct spec_fd *fd)
static int ds18x_access(struct spec_fd *fd)
{
if(!ow_reset(fd, 0))
return -EIO;
goto out;
if (0) {
/* select the rom among several of them */
if (ow_write_byte(fd, FD_OW_PORT, CMD_ROM_MATCH) < 0)
return -EIO;
goto out;
return ow_write_block(fd, FD_OW_PORT, fd->ds18_id, 8);
} else {
/* we have one only, so skip rom */
return ow_write_byte(fd, FD_OW_PORT, CMD_ROM_SKIP);
}
out:
pr_err("%s: Failure in one-wire communication\n", KBUILD_MODNAME);
return -EIO;
}
static void __temp_command_and_next_t(struct spec_fd *fd, int cfg_reg)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment