summaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/eeprom/eeprom_93cx6.c62
-rw-r--r--drivers/misc/enclosure.c44
2 files changed, 101 insertions, 5 deletions
diff --git a/drivers/misc/eeprom/eeprom_93cx6.c b/drivers/misc/eeprom/eeprom_93cx6.c
index 0ff4b02177be..0cf2c9d676be 100644
--- a/drivers/misc/eeprom/eeprom_93cx6.c
+++ b/drivers/misc/eeprom/eeprom_93cx6.c
@@ -170,7 +170,7 @@ static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
}
/**
- * eeprom_93cx6_read - Read multiple words from eeprom
+ * eeprom_93cx6_read - Read a word from eeprom
* @eeprom: Pointer to eeprom structure
* @word: Word index from where we should start reading
* @data: target pointer where the information will have to be stored
@@ -235,6 +235,66 @@ void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
/**
+ * eeprom_93cx6_readb - Read a byte from eeprom
+ * @eeprom: Pointer to eeprom structure
+ * @word: Byte index from where we should start reading
+ * @data: target pointer where the information will have to be stored
+ *
+ * This function will read a byte of the eeprom data
+ * into the given data pointer.
+ */
+void eeprom_93cx6_readb(struct eeprom_93cx6 *eeprom, const u8 byte,
+ u8 *data)
+{
+ u16 command;
+ u16 tmp;
+
+ /*
+ * Initialize the eeprom register
+ */
+ eeprom_93cx6_startup(eeprom);
+
+ /*
+ * Select the read opcode and the byte to be read.
+ */
+ command = (PCI_EEPROM_READ_OPCODE << (eeprom->width + 1)) | byte;
+ eeprom_93cx6_write_bits(eeprom, command,
+ PCI_EEPROM_WIDTH_OPCODE + eeprom->width + 1);
+
+ /*
+ * Read the requested 8 bits.
+ */
+ eeprom_93cx6_read_bits(eeprom, &tmp, 8);
+ *data = tmp & 0xff;
+
+ /*
+ * Cleanup eeprom register.
+ */
+ eeprom_93cx6_cleanup(eeprom);
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_readb);
+
+/**
+ * eeprom_93cx6_multireadb - Read multiple bytes from eeprom
+ * @eeprom: Pointer to eeprom structure
+ * @byte: Index from where we should start reading
+ * @data: target pointer where the information will have to be stored
+ * @words: Number of bytes that should be read.
+ *
+ * This function will read all requested bytes from the eeprom,
+ * this is done by calling eeprom_93cx6_readb() multiple times.
+ */
+void eeprom_93cx6_multireadb(struct eeprom_93cx6 *eeprom, const u8 byte,
+ u8 *data, const u16 bytes)
+{
+ unsigned int i;
+
+ for (i = 0; i < bytes; i++)
+ eeprom_93cx6_readb(eeprom, byte + i, &data[i]);
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_multireadb);
+
+/**
* eeprom_93cx6_wren - set the write enable state
* @eeprom: Pointer to eeprom structure
* @enable: true to enable writes, otherwise disable writes
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index 2cf2bbc0b927..180a5442fd4b 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -187,6 +187,7 @@ void enclosure_unregister(struct enclosure_device *edev)
EXPORT_SYMBOL_GPL(enclosure_unregister);
#define ENCLOSURE_NAME_SIZE 64
+#define COMPONENT_NAME_SIZE 64
static void enclosure_link_name(struct enclosure_component *cdev, char *name)
{
@@ -246,6 +247,29 @@ static void enclosure_component_release(struct device *dev)
put_device(dev->parent);
}
+static struct enclosure_component *
+enclosure_component_find_by_name(struct enclosure_device *edev,
+ const char *name)
+{
+ int i;
+ const char *cname;
+ struct enclosure_component *ecomp;
+
+ if (!edev || !name || !name[0])
+ return NULL;
+
+ for (i = 0; i < edev->components; i++) {
+ ecomp = &edev->component[i];
+ cname = dev_name(&ecomp->cdev);
+ if (ecomp->number != -1 &&
+ cname && cname[0] &&
+ !strcmp(cname, name))
+ return ecomp;
+ }
+
+ return NULL;
+}
+
static const struct attribute_group *enclosure_component_groups[];
/**
@@ -269,7 +293,8 @@ enclosure_component_register(struct enclosure_device *edev,
{
struct enclosure_component *ecomp;
struct device *cdev;
- int err;
+ int err, i;
+ char newname[COMPONENT_NAME_SIZE];
if (number >= edev->components)
return ERR_PTR(-EINVAL);
@@ -283,9 +308,20 @@ enclosure_component_register(struct enclosure_device *edev,
ecomp->number = number;
cdev = &ecomp->cdev;
cdev->parent = get_device(&edev->edev);
- if (name && name[0])
- dev_set_name(cdev, "%s", name);
- else
+
+ if (name && name[0]) {
+ /* Some hardware (e.g. enclosure in RX300 S6) has components
+ * with non unique names. Registering duplicates in sysfs
+ * will lead to warnings during bootup. So make the names
+ * unique by appending consecutive numbers -1, -2, ... */
+ i = 1;
+ snprintf(newname, COMPONENT_NAME_SIZE,
+ "%s", name);
+ while (enclosure_component_find_by_name(edev, newname))
+ snprintf(newname, COMPONENT_NAME_SIZE,
+ "%s-%i", name, i++);
+ dev_set_name(cdev, "%s", newname);
+ } else
dev_set_name(cdev, "%u", number);
cdev->release = enclosure_component_release;