migrate gateworks board support to the new at24 eeprom driver
SVN-Revision: 13450
This commit is contained in:
parent
7801e8d2bc
commit
083320dbe2
@ -0,0 +1,134 @@
|
|||||||
|
Subject: [PATCH 2/3] I2C: at24: add kernel interface for reading/writing EEPROM
|
||||||
|
Date: Monday 25 August 2008
|
||||||
|
From: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
To: davinci-linux-open-source@linux.davincidsp.com
|
||||||
|
|
||||||
|
This patch adds an interface by which other kernel code can read/write
|
||||||
|
detected EEPROM.
|
||||||
|
|
||||||
|
The platform code registers a 'setup' callback with the
|
||||||
|
at24_platform_data. When the at24 driver detects an EEPROM, it fills
|
||||||
|
out the read and write functions of at24_iface and calls the setup
|
||||||
|
callback. The platform code can then use the read/write functions in
|
||||||
|
the at24_iface struct for reading and writing the EEPROM.
|
||||||
|
|
||||||
|
Original idea, review and updates by David Brownell <david-b@pacbell.net>
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
---
|
||||||
|
drivers/i2c/chips/at24.c | 42 +++++++++++++++++++++++++++++++++++-------
|
||||||
|
include/linux/i2c/at24.h | 10 ++++++++++
|
||||||
|
2 files changed, 45 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/i2c/chips/at24.c
|
||||||
|
+++ b/drivers/i2c/chips/at24.c
|
||||||
|
@@ -53,6 +53,7 @@
|
||||||
|
|
||||||
|
struct at24_data {
|
||||||
|
struct at24_platform_data chip;
|
||||||
|
+ struct at24_iface iface;
|
||||||
|
bool use_smbus;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -264,13 +265,6 @@ static ssize_t at24_bin_read(struct kobj
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * REVISIT: export at24_bin{read,write}() to let other kernel code use
|
||||||
|
- * eeprom data. For example, it might hold a board's Ethernet address, or
|
||||||
|
- * board-specific calibration data generated on the manufacturing floor.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
* Note that if the hardware write-protect pin is pulled high, the whole
|
||||||
|
* chip is normally write protected. But there are plenty of product
|
||||||
|
* variants here, including OTP fuses and partial chip protect.
|
||||||
|
@@ -386,6 +380,30 @@ static ssize_t at24_bin_write(struct kob
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * This lets other kernel code access the eeprom data. For example, it
|
||||||
|
+ * might hold a board's Ethernet address, or board-specific calibration
|
||||||
|
+ * data generated on the manufacturing floor.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static ssize_t at24_iface_read(struct at24_iface *iface, char *buf,
|
||||||
|
+ off_t offset, size_t count)
|
||||||
|
+{
|
||||||
|
+ struct at24_data *at24 = container_of(iface, struct at24_data, iface);
|
||||||
|
+
|
||||||
|
+ return at24_eeprom_read(at24, buf, offset, count);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static ssize_t at24_iface_write(struct at24_iface *iface, char *buf,
|
||||||
|
+ off_t offset, size_t count)
|
||||||
|
+{
|
||||||
|
+ struct at24_data *at24 = container_of(iface, struct at24_data, iface);
|
||||||
|
+
|
||||||
|
+ return at24_eeprom_write(at24, buf, offset, count);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*-------------------------------------------------------------------------*/
|
||||||
|
+
|
||||||
|
static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
struct at24_platform_data chip;
|
||||||
|
@@ -413,6 +431,9 @@ static int at24_probe(struct i2c_client
|
||||||
|
* is recommended anyhow.
|
||||||
|
*/
|
||||||
|
chip.page_size = 1;
|
||||||
|
+
|
||||||
|
+ chip.setup = NULL;
|
||||||
|
+ chip.context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_power_of_2(chip.byte_len))
|
||||||
|
@@ -449,6 +470,9 @@ static int at24_probe(struct i2c_client
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ at24->iface.read = at24_iface_read;
|
||||||
|
+ at24->iface.write = at24_iface_write;
|
||||||
|
+
|
||||||
|
mutex_init(&at24->lock);
|
||||||
|
at24->use_smbus = use_smbus;
|
||||||
|
at24->chip = chip;
|
||||||
|
@@ -521,6 +545,10 @@ static int at24_probe(struct i2c_client
|
||||||
|
at24->write_max,
|
||||||
|
use_smbus ? ", use_smbus" : "");
|
||||||
|
|
||||||
|
+ /* export data to kernel code */
|
||||||
|
+ if (chip.setup)
|
||||||
|
+ chip.setup(&at24->iface, chip.context);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_clients:
|
||||||
|
--- a/include/linux/i2c/at24.h
|
||||||
|
+++ b/include/linux/i2c/at24.h
|
||||||
|
@@ -15,6 +15,13 @@
|
||||||
|
* is bigger than what the chip actually supports!
|
||||||
|
*/
|
||||||
|
|
||||||
|
+struct at24_iface {
|
||||||
|
+ ssize_t (*read)(struct at24_iface *, char *buf, off_t offset,
|
||||||
|
+ size_t count);
|
||||||
|
+ ssize_t (*write)(struct at24_iface *, char *buf, off_t offset,
|
||||||
|
+ size_t count);
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct at24_platform_data {
|
||||||
|
u32 byte_len; /* size (sum of all addr) */
|
||||||
|
u16 page_size; /* for writes */
|
||||||
|
@@ -23,6 +30,9 @@ struct at24_platform_data {
|
||||||
|
#define AT24_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */
|
||||||
|
#define AT24_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */
|
||||||
|
#define AT24_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */
|
||||||
|
+
|
||||||
|
+ int (*setup)(struct at24_iface *, void *context);
|
||||||
|
+ void *context;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _LINUX_AT24_H */
|
@ -55,7 +55,7 @@ CONFIG_ARM=y
|
|||||||
# CONFIG_ARM_THUMB is not set
|
# CONFIG_ARM_THUMB is not set
|
||||||
# CONFIG_ARPD is not set
|
# CONFIG_ARPD is not set
|
||||||
# CONFIG_ARTHUR is not set
|
# CONFIG_ARTHUR is not set
|
||||||
# CONFIG_AT24 is not set
|
CONFIG_AT24=y
|
||||||
CONFIG_ATA=m
|
CONFIG_ATA=m
|
||||||
# CONFIG_ATA_NONSTANDARD is not set
|
# CONFIG_ATA_NONSTANDARD is not set
|
||||||
# CONFIG_ATA_PIIX is not set
|
# CONFIG_ATA_PIIX is not set
|
||||||
@ -297,7 +297,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
|||||||
CONFIG_SCSI_WAIT_SCAN=m
|
CONFIG_SCSI_WAIT_SCAN=m
|
||||||
# CONFIG_SENSORS_AD7414 is not set
|
# CONFIG_SENSORS_AD7414 is not set
|
||||||
CONFIG_SENSORS_AD7418=y
|
CONFIG_SENSORS_AD7418=y
|
||||||
CONFIG_SENSORS_EEPROM=y
|
# CONFIG_SENSORS_EEPROM is not set
|
||||||
CONFIG_SENSORS_MAX6650=y
|
CONFIG_SENSORS_MAX6650=y
|
||||||
# CONFIG_SENSORS_PC87360 is not set
|
# CONFIG_SENSORS_PC87360 is not set
|
||||||
CONFIG_SENSORS_W83781D=y
|
CONFIG_SENSORS_W83781D=y
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h
|
||||||
|
+++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h
|
||||||
|
@@ -18,7 +18,7 @@
|
||||||
|
#define __ASM_ARCH_HARDWARE_H__
|
||||||
|
|
||||||
|
#define PCIBIOS_MIN_IO 0x00001000
|
||||||
|
-#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x40000000 : 0x48000000)
|
||||||
|
+#define PCIBIOS_MIN_MEM 0x48000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We override the standard dma-mask routines for bouncing.
|
@ -1,47 +1,3 @@
|
|||||||
--- a/arch/arm/mach-ixp4xx/Kconfig
|
|
||||||
+++ b/arch/arm/mach-ixp4xx/Kconfig
|
|
||||||
@@ -25,6 +25,14 @@ config MACH_AVILA
|
|
||||||
Avila Network Platform. For more information on this platform,
|
|
||||||
see <file:Documentation/arm/IXP4xx>.
|
|
||||||
|
|
||||||
+config MACH_CAMBRIA
|
|
||||||
+ bool "Cambria"
|
|
||||||
+ select PCI
|
|
||||||
+ help
|
|
||||||
+ Say 'Y' here if you want your kernel to support the Gateworks
|
|
||||||
+ Cambria series. For more information on this platform,
|
|
||||||
+ see <file:Documentation/arm/IXP4xx>.
|
|
||||||
+
|
|
||||||
config MACH_LOFT
|
|
||||||
bool "Loft"
|
|
||||||
depends on MACH_AVILA
|
|
||||||
@@ -208,7 +216,7 @@ config CPU_IXP46X
|
|
||||||
|
|
||||||
config CPU_IXP43X
|
|
||||||
bool
|
|
||||||
- depends on MACH_KIXRP435
|
|
||||||
+ depends on MACH_KIXRP435 || MACH_CAMBRIA
|
|
||||||
default y
|
|
||||||
|
|
||||||
config MACH_GTWX5715
|
|
||||||
--- a/arch/arm/mach-ixp4xx/Makefile
|
|
||||||
+++ b/arch/arm/mach-ixp4xx/Makefile
|
|
||||||
@@ -7,6 +7,7 @@ obj-pci-n :=
|
|
||||||
|
|
||||||
obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o
|
|
||||||
obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o
|
|
||||||
+obj-pci-$(CONFIG_MACH_CAMBRIA) += cambria-pci.o
|
|
||||||
obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o
|
|
||||||
obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o
|
|
||||||
obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
|
|
||||||
@@ -28,6 +29,7 @@ obj-y += common.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o
|
|
||||||
obj-$(CONFIG_MACH_AVILA) += avila-setup.o
|
|
||||||
+obj-$(CONFIG_MACH_CAMBRIA) += cambria-setup.o
|
|
||||||
obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o
|
|
||||||
obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o
|
|
||||||
obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
|
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/arch/arm/mach-ixp4xx/cambria-pci.c
|
+++ b/arch/arm/mach-ixp4xx/cambria-pci.c
|
||||||
@@ -0,0 +1,74 @@
|
@@ -0,0 +1,74 @@
|
||||||
@ -121,49 +77,47 @@
|
|||||||
+subsys_initcall(cambria_pci_init);
|
+subsys_initcall(cambria_pci_init);
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/arch/arm/mach-ixp4xx/cambria-setup.c
|
+++ b/arch/arm/mach-ixp4xx/cambria-setup.c
|
||||||
@@ -0,0 +1,444 @@
|
@@ -0,0 +1,429 @@
|
||||||
+/*
|
+/*
|
||||||
+ * arch/arm/mach-ixp4xx/cambria-setup.c
|
+ * arch/arm/mach-ixp4xx/cambria-setup.c
|
||||||
+ *
|
+ *
|
||||||
+ * Board setup for the Gateworks Cambria series
|
+ * Board setup for the Gateworks Cambria series
|
||||||
+ *
|
+ *
|
||||||
+ * Copyright (C) 2008 Imre Kaloz <Kaloz@openwrt.org>
|
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||||
+ *
|
+ *
|
||||||
+ * based on coyote-setup.c:
|
+ * based on coyote-setup.c:
|
||||||
+ * Copyright (C) 2003-2005 MontaVista Software, Inc.
|
+ * Copyright (C) 2003-2005 MontaVista Software, Inc.
|
||||||
+ *
|
+ *
|
||||||
+ * Author: Imre Kaloz <Kaloz@openwrt.org>
|
+ * Author: Imre Kaloz <kaloz@openwrt.org>
|
||||||
+ */
|
+ */
|
||||||
+
|
+
|
||||||
+#include <linux/kernel.h>
|
|
||||||
+#include <linux/init.h>
|
|
||||||
+#include <linux/device.h>
|
+#include <linux/device.h>
|
||||||
|
+#include <linux/i2c.h>
|
||||||
|
+#include <linux/i2c-gpio.h>
|
||||||
|
+#include <linux/i2c/at24.h>
|
||||||
+#include <linux/if_ether.h>
|
+#include <linux/if_ether.h>
|
||||||
+#include <linux/socket.h>
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/leds.h>
|
||||||
|
+#include <linux/memory.h>
|
||||||
+#include <linux/netdevice.h>
|
+#include <linux/netdevice.h>
|
||||||
+#include <linux/serial.h>
|
+#include <linux/serial.h>
|
||||||
+#include <linux/tty.h>
|
|
||||||
+#include <linux/serial_8250.h>
|
+#include <linux/serial_8250.h>
|
||||||
+#include <linux/slab.h>
|
+#include <linux/slab.h>
|
||||||
+#ifdef CONFIG_SENSORS_EEPROM
|
+#include <linux/socket.h>
|
||||||
+# include <linux/i2c.h>
|
+#include <linux/types.h>
|
||||||
+# include <linux/eeprom.h>
|
+#include <linux/tty.h>
|
||||||
+#endif
|
|
||||||
+
|
+
|
||||||
+#include <linux/leds.h>
|
|
||||||
+#include <linux/i2c-gpio.h>
|
|
||||||
+#include <asm/types.h>
|
|
||||||
+#include <asm/setup.h>
|
|
||||||
+#include <asm/memory.h>
|
|
||||||
+#include <mach/hardware.h>
|
+#include <mach/hardware.h>
|
||||||
+#include <asm/irq.h>
|
+#include <asm/irq.h>
|
||||||
+#include <asm/mach-types.h>
|
+#include <asm/mach-types.h>
|
||||||
+#include <asm/mach/arch.h>
|
+#include <asm/mach/arch.h>
|
||||||
+#include <asm/mach/flash.h>
|
+#include <asm/mach/flash.h>
|
||||||
|
+#include <asm/setup.h>
|
||||||
+
|
+
|
||||||
+struct cambria_board_info {
|
+struct cambria_board_info {
|
||||||
+ unsigned char *model;
|
+ unsigned char *model;
|
||||||
+ void (* setup)(void);
|
+ void (*setup)(void);
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static struct cambria_board_info *cambria_info __initdata;
|
+static struct cambria_board_info *cambria_info __initdata;
|
||||||
@ -200,6 +154,30 @@
|
|||||||
+ },
|
+ },
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
|
+static struct eth_plat_info cambria_npec_data = {
|
||||||
|
+ .phy = 1,
|
||||||
|
+ .rxq = 4,
|
||||||
|
+ .txreadyq = 21,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct eth_plat_info cambria_npea_data = {
|
||||||
|
+ .phy = 2,
|
||||||
|
+ .rxq = 2,
|
||||||
|
+ .txreadyq = 19,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device cambria_npec_device = {
|
||||||
|
+ .name = "ixp4xx_eth",
|
||||||
|
+ .id = IXP4XX_ETH_NPEC,
|
||||||
|
+ .dev.platform_data = &cambria_npec_data,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device cambria_npea_device = {
|
||||||
|
+ .name = "ixp4xx_eth",
|
||||||
|
+ .id = IXP4XX_ETH_NPEA,
|
||||||
|
+ .dev.platform_data = &cambria_npea_data,
|
||||||
|
+};
|
||||||
|
+
|
||||||
+static struct resource cambria_uart_resource = {
|
+static struct resource cambria_uart_resource = {
|
||||||
+ .start = IXP4XX_UART1_BASE_PHYS,
|
+ .start = IXP4XX_UART1_BASE_PHYS,
|
||||||
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
|
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
|
||||||
@ -257,30 +235,6 @@
|
|||||||
+ .resource = cambria_pata_resources,
|
+ .resource = cambria_pata_resources,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static struct eth_plat_info cambria_npec_data = {
|
|
||||||
+ .phy = 1,
|
|
||||||
+ .rxq = 4,
|
|
||||||
+ .txreadyq = 21,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct eth_plat_info cambria_npea_data = {
|
|
||||||
+ .phy = 2,
|
|
||||||
+ .rxq = 2,
|
|
||||||
+ .txreadyq = 19,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct platform_device cambria_npec_device = {
|
|
||||||
+ .name = "ixp4xx_eth",
|
|
||||||
+ .id = IXP4XX_ETH_NPEC,
|
|
||||||
+ .dev.platform_data = &cambria_npec_data,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct platform_device cambria_npea_device = {
|
|
||||||
+ .name = "ixp4xx_eth",
|
|
||||||
+ .id = IXP4XX_ETH_NPEA,
|
|
||||||
+ .dev.platform_data = &cambria_npea_data,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct gpio_led cambria_gpio_leds[] = {
|
+static struct gpio_led cambria_gpio_leds[] = {
|
||||||
+ {
|
+ {
|
||||||
+ .name = "user", /* green led */
|
+ .name = "user", /* green led */
|
||||||
@ -300,7 +254,6 @@
|
|||||||
+ .dev.platform_data = &cambria_gpio_leds_data,
|
+ .dev.platform_data = &cambria_gpio_leds_data,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+
|
|
||||||
+static struct latch_led cambria_latch_leds[] = {
|
+static struct latch_led cambria_latch_leds[] = {
|
||||||
+ {
|
+ {
|
||||||
+ .name = "ledA", /* green led */
|
+ .name = "ledA", /* green led */
|
||||||
@ -408,7 +361,6 @@
|
|||||||
+ platform_device_register(&cambria_npea_device);
|
+ platform_device_register(&cambria_npea_device);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+#ifdef CONFIG_SENSORS_EEPROM
|
|
||||||
+static void __init cambria_gw2350_setup(void)
|
+static void __init cambria_gw2350_setup(void)
|
||||||
+{
|
+{
|
||||||
+ platform_device_register(&cambria_npec_device);
|
+ platform_device_register(&cambria_npec_device);
|
||||||
@ -449,67 +401,58 @@
|
|||||||
+
|
+
|
||||||
+ for (i = 0; i < ARRAY_SIZE(cambria_boards); i++) {
|
+ for (i = 0; i < ARRAY_SIZE(cambria_boards); i++) {
|
||||||
+ struct cambria_board_info *info = &cambria_boards[i];
|
+ struct cambria_board_info *info = &cambria_boards[i];
|
||||||
+ if (strncmp(info->model, model, strlen(info->model)) == 0)
|
+ if (strcmp(info->model, model) == 0)
|
||||||
+ return info;
|
+ return info;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ return NULL;
|
+ return NULL;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+struct cambria_eeprom_header {
|
+static struct at24_iface *at24_if;
|
||||||
+ unsigned char mac0[ETH_ALEN];
|
+
|
||||||
+ unsigned char mac1[ETH_ALEN];
|
+static int at24_setup(struct at24_iface *iface, void *context)
|
||||||
+ unsigned char res0[4];
|
+{
|
||||||
+ unsigned char magic[2];
|
+ char mac_addr[ETH_ALEN];
|
||||||
+ unsigned char config[14];
|
+ char model[6];
|
||||||
+ unsigned char model[16];
|
+
|
||||||
|
+ at24_if = iface;
|
||||||
|
+
|
||||||
|
+ /* Read MAC addresses */
|
||||||
|
+ if (at24_if->read(at24_if, mac_addr, 0x0, 6) == 6) {
|
||||||
|
+ memcpy(&cambria_npec_data.hwaddr, mac_addr, ETH_ALEN);
|
||||||
|
+ }
|
||||||
|
+ if (at24_if->read(at24_if, mac_addr, 0x6, 6) == 6) {
|
||||||
|
+ memcpy(&cambria_npea_data.hwaddr, mac_addr, ETH_ALEN);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Read the first 6 bytes of the model number */
|
||||||
|
+ if (at24_if->read(at24_if, model, 0x20, 6) == 6) {
|
||||||
|
+ cambria_info = cambria_find_board_info(model);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct at24_platform_data cambria_eeprom_info = {
|
||||||
|
+ .byte_len = 1024,
|
||||||
|
+ .page_size = 16,
|
||||||
|
+ .flags = AT24_FLAG_READONLY,
|
||||||
|
+ .setup = at24_setup,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static int __init cambria_eeprom_notify(struct notifier_block *self,
|
+static struct i2c_board_info __initdata cambria_i2c_board_info[] = {
|
||||||
+ unsigned long event, void *t)
|
+/* {
|
||||||
+{
|
+ I2C_BOARD_INFO("rtc-ds1672", 0x68),
|
||||||
+ struct eeprom_data *ee = t;
|
+ },*/
|
||||||
+ struct cambria_eeprom_header hdr;
|
+ {
|
||||||
+
|
+ I2C_BOARD_INFO("ad7418", 0x28),
|
||||||
+ if (cambria_info)
|
+ },
|
||||||
+ return NOTIFY_DONE;
|
+ {
|
||||||
+
|
+ I2C_BOARD_INFO("24c08", 0x51),
|
||||||
+ /* The eeprom is at address 0x51 */
|
+ .platform_data = &cambria_eeprom_info
|
||||||
+ if (event != EEPROM_REGISTER || ee->client.addr != 0x51)
|
+ },
|
||||||
+ return NOTIFY_DONE;
|
|
||||||
+
|
|
||||||
+ ee->attr->read(&ee->client.dev.kobj, ee->attr, (char *)&hdr,
|
|
||||||
+ 0, sizeof(hdr));
|
|
||||||
+
|
|
||||||
+ if (hdr.magic[0] != 'G' || hdr.magic[1] != 'W')
|
|
||||||
+ return NOTIFY_DONE;
|
|
||||||
+
|
|
||||||
+ memcpy(&cambria_npec_data.hwaddr, hdr.mac0, ETH_ALEN);
|
|
||||||
+ memcpy(&cambria_npea_data.hwaddr, hdr.mac1, ETH_ALEN);
|
|
||||||
+
|
|
||||||
+ cambria_info = cambria_find_board_info(hdr.model);
|
|
||||||
+
|
|
||||||
+ return NOTIFY_OK;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct notifier_block cambria_eeprom_notifier __initdata = {
|
|
||||||
+ .notifier_call = cambria_eeprom_notify
|
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static void __init cambria_register_eeprom_notifier(void)
|
|
||||||
+{
|
|
||||||
+ register_eeprom_notifier(&cambria_eeprom_notifier);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __init cambria_unregister_eeprom_notifier(void)
|
|
||||||
+{
|
|
||||||
+ unregister_eeprom_notifier(&cambria_eeprom_notifier);
|
|
||||||
+}
|
|
||||||
+#else /* CONFIG_SENSORS_EEPROM */
|
|
||||||
+static inline void cambria_register_eeprom_notifier(void) {};
|
|
||||||
+static inline void cambria_unregister_eeprom_notifier(void) {};
|
|
||||||
+#endif /* CONFIG_SENSORS_EEPROM */
|
|
||||||
+
|
|
||||||
+static void __init cambria_init(void)
|
+static void __init cambria_init(void)
|
||||||
+{
|
+{
|
||||||
+ ixp4xx_sys_init();
|
+ ixp4xx_sys_init();
|
||||||
@ -531,7 +474,8 @@
|
|||||||
+ cambria_pata_data.cs0_cfg = IXP4XX_EXP_CS3;
|
+ cambria_pata_data.cs0_cfg = IXP4XX_EXP_CS3;
|
||||||
+ cambria_pata_data.cs1_cfg = IXP4XX_EXP_CS3;
|
+ cambria_pata_data.cs1_cfg = IXP4XX_EXP_CS3;
|
||||||
+
|
+
|
||||||
+ cambria_register_eeprom_notifier();
|
+ i2c_register_board_info(0, cambria_i2c_board_info,
|
||||||
|
+ ARRAY_SIZE(cambria_i2c_board_info));
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int __init cambria_model_setup(void)
|
+static int __init cambria_model_setup(void)
|
||||||
@ -549,12 +493,10 @@
|
|||||||
+ cambria_gw23xx_setup();
|
+ cambria_gw23xx_setup();
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ cambria_unregister_eeprom_notifier();
|
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+late_initcall(cambria_model_setup);
|
+late_initcall(cambria_model_setup);
|
||||||
+
|
+
|
||||||
+#ifdef CONFIG_MACH_CAMBRIA
|
|
||||||
+MACHINE_START(CAMBRIA, "Gateworks Cambria series")
|
+MACHINE_START(CAMBRIA, "Gateworks Cambria series")
|
||||||
+ /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
|
+ /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
|
||||||
+ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
+ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||||
@ -565,15 +507,47 @@
|
|||||||
+ .boot_params = 0x0100,
|
+ .boot_params = 0x0100,
|
||||||
+ .init_machine = cambria_init,
|
+ .init_machine = cambria_init,
|
||||||
+MACHINE_END
|
+MACHINE_END
|
||||||
+#endif
|
--- a/arch/arm/mach-ixp4xx/Kconfig
|
||||||
--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h
|
+++ b/arch/arm/mach-ixp4xx/Kconfig
|
||||||
+++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h
|
@@ -25,6 +25,14 @@ config MACH_AVILA
|
||||||
@@ -18,7 +18,7 @@
|
Avila Network Platform. For more information on this platform,
|
||||||
#define __ASM_ARCH_HARDWARE_H__
|
see <file:Documentation/arm/IXP4xx>.
|
||||||
|
|
||||||
#define PCIBIOS_MIN_IO 0x00001000
|
+config MACH_CAMBRIA
|
||||||
-#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x40000000 : 0x48000000)
|
+ bool "Cambria"
|
||||||
+#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x48000000 : 0x48000000)
|
+ select PCI
|
||||||
|
+ help
|
||||||
|
+ Say 'Y' here if you want your kernel to support the Gateworks
|
||||||
|
+ Cambria series. For more information on this platform,
|
||||||
|
+ see <file:Documentation/arm/IXP4xx>.
|
||||||
|
+
|
||||||
|
config MACH_LOFT
|
||||||
|
bool "Loft"
|
||||||
|
depends on MACH_AVILA
|
||||||
|
@@ -208,7 +216,7 @@ config CPU_IXP46X
|
||||||
|
|
||||||
/*
|
config CPU_IXP43X
|
||||||
* We override the standard dma-mask routines for bouncing.
|
bool
|
||||||
|
- depends on MACH_KIXRP435
|
||||||
|
+ depends on MACH_KIXRP435 || MACH_CAMBRIA
|
||||||
|
default y
|
||||||
|
|
||||||
|
config MACH_GTWX5715
|
||||||
|
--- a/arch/arm/mach-ixp4xx/Makefile
|
||||||
|
+++ b/arch/arm/mach-ixp4xx/Makefile
|
||||||
|
@@ -7,6 +7,7 @@ obj-pci-n :=
|
||||||
|
|
||||||
|
obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o
|
||||||
|
obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o
|
||||||
|
+obj-pci-$(CONFIG_MACH_CAMBRIA) += cambria-pci.o
|
||||||
|
obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o
|
||||||
|
obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o
|
||||||
|
obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
|
||||||
|
@@ -29,6 +30,7 @@ obj-y += common.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o
|
||||||
|
obj-$(CONFIG_MACH_AVILA) += avila-setup.o
|
||||||
|
+obj-$(CONFIG_MACH_CAMBRIA) += cambria-setup.o
|
||||||
|
obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o
|
||||||
|
obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o
|
||||||
|
obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
--- a/arch/arm/mach-ixp4xx/cambria-setup.c
|
--- a/arch/arm/mach-ixp4xx/cambria-setup.c
|
||||||
+++ b/arch/arm/mach-ixp4xx/cambria-setup.c
|
+++ b/arch/arm/mach-ixp4xx/cambria-setup.c
|
||||||
@@ -36,6 +36,7 @@
|
@@ -34,6 +34,7 @@
|
||||||
#include <asm/mach-types.h>
|
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/mach/flash.h>
|
#include <asm/mach/flash.h>
|
||||||
|
#include <asm/setup.h>
|
||||||
+#include <linux/irq.h>
|
+#include <linux/irq.h>
|
||||||
|
|
||||||
struct cambria_board_info {
|
struct cambria_board_info {
|
||||||
unsigned char *model;
|
unsigned char *model;
|
||||||
@@ -105,6 +106,43 @@ static struct platform_device cambria_ua
|
@@ -127,6 +128,43 @@ static struct platform_device cambria_ua
|
||||||
.resource = &cambria_uart_resource,
|
.resource = &cambria_uart_resource,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,8 +52,8 @@
|
|||||||
static struct resource cambria_pata_resources[] = {
|
static struct resource cambria_pata_resources[] = {
|
||||||
{
|
{
|
||||||
.flags = IORESOURCE_MEM
|
.flags = IORESOURCE_MEM
|
||||||
@@ -287,6 +325,19 @@ static void __init cambria_gw23xx_setup(
|
@@ -283,6 +321,19 @@ static void __init cambria_gw23xx_setup(
|
||||||
#ifdef CONFIG_SENSORS_EEPROM
|
|
||||||
static void __init cambria_gw2350_setup(void)
|
static void __init cambria_gw2350_setup(void)
|
||||||
{
|
{
|
||||||
+ *IXP4XX_EXP_CS2 = 0xbfff0003;
|
+ *IXP4XX_EXP_CS2 = 0xbfff0003;
|
||||||
@ -72,7 +72,7 @@
|
|||||||
platform_device_register(&cambria_npec_device);
|
platform_device_register(&cambria_npec_device);
|
||||||
platform_device_register(&cambria_npea_device);
|
platform_device_register(&cambria_npea_device);
|
||||||
|
|
||||||
@@ -294,10 +345,26 @@ static void __init cambria_gw2350_setup(
|
@@ -290,10 +341,26 @@ static void __init cambria_gw2350_setup(
|
||||||
platform_device_register(&cambria_usb1_device);
|
platform_device_register(&cambria_usb1_device);
|
||||||
|
|
||||||
platform_device_register(&cambria_gpio_leds_device);
|
platform_device_register(&cambria_gpio_leds_device);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/arch/arm/mach-ixp4xx/cambria-setup.c
|
--- a/arch/arm/mach-ixp4xx/cambria-setup.c
|
||||||
+++ b/arch/arm/mach-ixp4xx/cambria-setup.c
|
+++ b/arch/arm/mach-ixp4xx/cambria-setup.c
|
||||||
@@ -214,6 +214,21 @@ static struct platform_device cambria_gp
|
@@ -212,6 +212,20 @@ static struct platform_device cambria_gp
|
||||||
.dev.platform_data = &cambria_gpio_leds_data,
|
.dev.platform_data = &cambria_gpio_leds_data,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,11 +18,10 @@
|
|||||||
+ .resource = cambria_gpio_resources,
|
+ .resource = cambria_gpio_resources,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+
|
|
||||||
|
|
||||||
static struct latch_led cambria_latch_leds[] = {
|
static struct latch_led cambria_latch_leds[] = {
|
||||||
{
|
{
|
||||||
@@ -337,6 +352,11 @@ static void __init cambria_gw2350_setup(
|
.name = "ledA", /* green led */
|
||||||
|
@@ -333,6 +347,11 @@ static void __init cambria_gw2350_setup(
|
||||||
cambria_optional_uart_data[1].membase = (void __iomem *)ioremap(0x53FF0000, 0x0fff);
|
cambria_optional_uart_data[1].membase = (void __iomem *)ioremap(0x53FF0000, 0x0fff);
|
||||||
cambria_optional_uart_data[1].irq = IRQ_IXP4XX_GPIO4;
|
cambria_optional_uart_data[1].irq = IRQ_IXP4XX_GPIO4;
|
||||||
|
|
||||||
@ -34,7 +33,7 @@
|
|||||||
platform_device_register(&cambria_optional_uart);
|
platform_device_register(&cambria_optional_uart);
|
||||||
platform_device_register(&cambria_npec_device);
|
platform_device_register(&cambria_npec_device);
|
||||||
platform_device_register(&cambria_npea_device);
|
platform_device_register(&cambria_npea_device);
|
||||||
@@ -363,6 +383,10 @@ static void __init cambria_gw2358_setup(
|
@@ -359,6 +378,10 @@ static void __init cambria_gw2358_setup(
|
||||||
cambria_optional_uart_data[1].membase = (void __iomem *)ioremap(0x53F80000, 0x0fff);
|
cambria_optional_uart_data[1].membase = (void __iomem *)ioremap(0x53F80000, 0x0fff);
|
||||||
cambria_optional_uart_data[1].irq = IRQ_IXP4XX_GPIO4;
|
cambria_optional_uart_data[1].irq = IRQ_IXP4XX_GPIO4;
|
||||||
|
|
||||||
|
@ -1,183 +0,0 @@
|
|||||||
--- a/drivers/i2c/chips/eeprom.c
|
|
||||||
+++ b/drivers/i2c/chips/eeprom.c
|
|
||||||
@@ -27,6 +27,8 @@
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
#include <linux/i2c.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
+#include <linux/notifier.h>
|
|
||||||
+#include <linux/eeprom.h>
|
|
||||||
|
|
||||||
/* Addresses to scan */
|
|
||||||
static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
|
|
||||||
@@ -35,25 +37,7 @@ static const unsigned short normal_i2c[]
|
|
||||||
/* Insmod parameters */
|
|
||||||
I2C_CLIENT_INSMOD_1(eeprom);
|
|
||||||
|
|
||||||
-
|
|
||||||
-/* Size of EEPROM in bytes */
|
|
||||||
-#define EEPROM_SIZE 256
|
|
||||||
-
|
|
||||||
-/* possible types of eeprom devices */
|
|
||||||
-enum eeprom_nature {
|
|
||||||
- UNKNOWN,
|
|
||||||
- VAIO,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-/* Each client has this additional data */
|
|
||||||
-struct eeprom_data {
|
|
||||||
- struct mutex update_lock;
|
|
||||||
- u8 valid; /* bitfield, bit!=0 if slice is valid */
|
|
||||||
- unsigned long last_updated[8]; /* In jiffies, 8 slices */
|
|
||||||
- u8 data[EEPROM_SIZE]; /* Register values */
|
|
||||||
- enum eeprom_nature nature;
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
+ATOMIC_NOTIFIER_HEAD(eeprom_chain);
|
|
||||||
|
|
||||||
static void eeprom_update_client(struct i2c_client *client, u8 slice)
|
|
||||||
{
|
|
||||||
@@ -178,6 +162,7 @@ static int eeprom_probe(struct i2c_clien
|
|
||||||
i2c_set_clientdata(client, data);
|
|
||||||
mutex_init(&data->update_lock);
|
|
||||||
data->nature = UNKNOWN;
|
|
||||||
+ data->attr = &eeprom_attr;
|
|
||||||
|
|
||||||
/* Detect the Vaio nature of EEPROMs.
|
|
||||||
We use the "PCG-" or "VGN-" prefix as the signature. */
|
|
||||||
@@ -202,6 +187,9 @@ static int eeprom_probe(struct i2c_clien
|
|
||||||
if (err)
|
|
||||||
goto exit_kfree;
|
|
||||||
|
|
||||||
+ /* call the notifier chain */
|
|
||||||
+ atomic_notifier_call_chain(&eeprom_chain, EEPROM_REGISTER, data);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
exit_kfree:
|
|
||||||
@@ -236,6 +224,41 @@ static struct i2c_driver eeprom_driver =
|
|
||||||
.address_data = &addr_data,
|
|
||||||
};
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * register_eeprom_notifier - register a 'user' of EEPROM devices.
|
|
||||||
+ * @nb: pointer to notifier info structure
|
|
||||||
+ *
|
|
||||||
+ * Registers a callback function to be called upon detection
|
|
||||||
+ * of an EEPROM device. Detection invokes the 'add' callback
|
|
||||||
+ * with the kobj of the mutex and a bin_attribute which allows
|
|
||||||
+ * read from the EEPROM. The intention is that the notifier
|
|
||||||
+ * will be able to read system configuration from the notifier.
|
|
||||||
+ *
|
|
||||||
+ * Only EEPROMs detected *after* the addition of the notifier
|
|
||||||
+ * are notified. I.e. EEPROMs already known to the system
|
|
||||||
+ * will not be notified - add the notifier from board level
|
|
||||||
+ * code!
|
|
||||||
+ */
|
|
||||||
+int register_eeprom_notifier(struct notifier_block *nb)
|
|
||||||
+{
|
|
||||||
+ return atomic_notifier_chain_register(&eeprom_chain, nb);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * unregister_eeprom_notifier - unregister a 'user' of EEPROM devices.
|
|
||||||
+ * @old: pointer to notifier info structure
|
|
||||||
+ *
|
|
||||||
+ * Removes a callback function from the list of 'users' to be
|
|
||||||
+ * notified upon detection of EEPROM devices.
|
|
||||||
+ */
|
|
||||||
+int unregister_eeprom_notifier(struct notifier_block *nb)
|
|
||||||
+{
|
|
||||||
+ return atomic_notifier_chain_unregister(&eeprom_chain, nb);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+EXPORT_SYMBOL_GPL(register_eeprom_notifier);
|
|
||||||
+EXPORT_SYMBOL_GPL(unregister_eeprom_notifier);
|
|
||||||
+
|
|
||||||
static int __init eeprom_init(void)
|
|
||||||
{
|
|
||||||
return i2c_add_driver(&eeprom_driver);
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/linux/eeprom.h
|
|
||||||
@@ -0,0 +1,71 @@
|
|
||||||
+#ifndef _LINUX_EEPROM_H
|
|
||||||
+#define _LINUX_EEPROM_H
|
|
||||||
+/*
|
|
||||||
+ * EEPROM notifier header
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2006 John Bowler
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * 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, or
|
|
||||||
+ * (at your option) any later version.
|
|
||||||
+ *
|
|
||||||
+ * This program is distributed in the hope that it will be useful,
|
|
||||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
+ * GNU General Public License for more details.
|
|
||||||
+ *
|
|
||||||
+ * You should have received a copy of the GNU General Public License
|
|
||||||
+ * along with this program; if not, write to the Free Software
|
|
||||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef __KERNEL__
|
|
||||||
+#error This is a kernel header
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#include <linux/list.h>
|
|
||||||
+#include <linux/kobject.h>
|
|
||||||
+#include <linux/sysfs.h>
|
|
||||||
+
|
|
||||||
+/* Size of EEPROM in bytes */
|
|
||||||
+#define EEPROM_SIZE 256
|
|
||||||
+
|
|
||||||
+/* possible types of eeprom devices */
|
|
||||||
+enum eeprom_nature {
|
|
||||||
+ UNKNOWN,
|
|
||||||
+ VAIO,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+/* Each client has this additional data */
|
|
||||||
+struct eeprom_data {
|
|
||||||
+ struct i2c_client client;
|
|
||||||
+ struct mutex update_lock;
|
|
||||||
+ u8 valid; /* bitfield, bit!=0 if slice is valid */
|
|
||||||
+ unsigned long last_updated[8]; /* In jiffies, 8 slices */
|
|
||||||
+ u8 data[EEPROM_SIZE]; /* Register values */
|
|
||||||
+ enum eeprom_nature nature;
|
|
||||||
+ struct bin_attribute *attr;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * This is very basic.
|
|
||||||
+ *
|
|
||||||
+ * If an EEPROM is detected on the I2C bus (this only works for
|
|
||||||
+ * I2C EEPROMs) the notifier chain is called with
|
|
||||||
+ * both the I2C information and the kobject for the sysfs
|
|
||||||
+ * device which has been registers. It is then possible to
|
|
||||||
+ * read from the device via the bin_attribute::read method
|
|
||||||
+ * to extract configuration information.
|
|
||||||
+ *
|
|
||||||
+ * Register the notifier in the board level code, there is no
|
|
||||||
+ * need to unregister it but you can if you want (it will save
|
|
||||||
+ * a little bit or kernel memory to do so).
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+extern int register_eeprom_notifier(struct notifier_block *nb);
|
|
||||||
+extern int unregister_eeprom_notifier(struct notifier_block *nb);
|
|
||||||
+
|
|
||||||
+#endif /* _LINUX_EEPROM_H */
|
|
||||||
--- a/include/linux/notifier.h
|
|
||||||
+++ b/include/linux/notifier.h
|
|
||||||
@@ -256,5 +256,8 @@ extern struct blocking_notifier_head reb
|
|
||||||
#define VT_UPDATE 0x0004 /* A bigger update occurred */
|
|
||||||
#define VT_PREWRITE 0x0005 /* A char is about to be written to the console */
|
|
||||||
|
|
||||||
+/* eeprom notifier chain */
|
|
||||||
+#define EEPROM_REGISTER 0x0001
|
|
||||||
+
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
#endif /* _LINUX_NOTIFIER_H */
|
|
@ -1,43 +0,0 @@
|
|||||||
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
|
||||||
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
|
||||||
@@ -132,6 +132,31 @@ static struct platform_device avila_pata
|
|
||||||
.resource = avila_pata_resources,
|
|
||||||
};
|
|
||||||
|
|
||||||
+/* Built-in 10/100 Ethernet MAC interfaces */
|
|
||||||
+static struct eth_plat_info avila_npeb_data = {
|
|
||||||
+ .phy = 0,
|
|
||||||
+ .rxq = 3,
|
|
||||||
+ .txreadyq = 20,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct eth_plat_info avila_npec_data = {
|
|
||||||
+ .phy = 1,
|
|
||||||
+ .rxq = 4,
|
|
||||||
+ .txreadyq = 21,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct platform_device avila_npeb_device = {
|
|
||||||
+ .name = "ixp4xx_eth",
|
|
||||||
+ .id = IXP4XX_ETH_NPEB,
|
|
||||||
+ .dev.platform_data = &avila_npeb_data,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct platform_device avila_npec_device = {
|
|
||||||
+ .name = "ixp4xx_eth",
|
|
||||||
+ .id = IXP4XX_ETH_NPEC,
|
|
||||||
+ .dev.platform_data = &avila_npec_data,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static struct platform_device *avila_devices[] __initdata = {
|
|
||||||
&avila_i2c_gpio,
|
|
||||||
&avila_flash,
|
|
||||||
@@ -159,6 +184,8 @@ static void __init avila_init(void)
|
|
||||||
|
|
||||||
platform_device_register(&avila_pata);
|
|
||||||
|
|
||||||
+ platform_device_register(avila_npeb_device);
|
|
||||||
+ platform_device_register(avila_npec_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
MACHINE_START(AVILA, "Gateworks Avila Network Platform")
|
|
@ -1,6 +1,6 @@
|
|||||||
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
||||||
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
||||||
@@ -14,10 +14,18 @@
|
@@ -14,10 +14,16 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
@ -11,21 +11,19 @@
|
|||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/serial_8250.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
+#ifdef CONFIG_SENSORS_EEPROM
|
+#include <linux/i2c.h>
|
||||||
+# include <linux/i2c.h>
|
+#include <linux/i2c/at24.h>
|
||||||
+# include <linux/eeprom.h>
|
|
||||||
+#endif
|
|
||||||
+
|
+
|
||||||
#include <linux/i2c-gpio.h>
|
#include <linux/i2c-gpio.h>
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
@@ -29,6 +37,13 @@
|
@@ -29,6 +35,13 @@
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/mach/flash.h>
|
#include <asm/mach/flash.h>
|
||||||
|
|
||||||
+struct avila_board_info {
|
+struct avila_board_info {
|
||||||
+ unsigned char *model;
|
+ unsigned char *model;
|
||||||
+ void (* setup)(void);
|
+ void (*setup)(void);
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static struct avila_board_info *avila_info __initdata;
|
+static struct avila_board_info *avila_info __initdata;
|
||||||
@ -33,7 +31,38 @@
|
|||||||
static struct flash_platform_data avila_flash_data = {
|
static struct flash_platform_data avila_flash_data = {
|
||||||
.map_name = "cfi_probe",
|
.map_name = "cfi_probe",
|
||||||
.width = 2,
|
.width = 2,
|
||||||
@@ -163,10 +178,160 @@ static struct platform_device *avila_dev
|
@@ -132,16 +145,181 @@ static struct platform_device avila_pata
|
||||||
|
.resource = avila_pata_resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* Built-in 10/100 Ethernet MAC interfaces */
|
||||||
|
+static struct eth_plat_info avila_npeb_data = {
|
||||||
|
+ .phy = 0,
|
||||||
|
+ .rxq = 3,
|
||||||
|
+ .txreadyq = 20,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct eth_plat_info avila_npec_data = {
|
||||||
|
+ .phy = 1,
|
||||||
|
+ .rxq = 4,
|
||||||
|
+ .txreadyq = 21,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device avila_npeb_device = {
|
||||||
|
+ .name = "ixp4xx_eth",
|
||||||
|
+ .id = IXP4XX_ETH_NPEB,
|
||||||
|
+ .dev.platform_data = &avila_npeb_data,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device avila_npec_device = {
|
||||||
|
+ .name = "ixp4xx_eth",
|
||||||
|
+ .id = IXP4XX_ETH_NPEC,
|
||||||
|
+ .dev.platform_data = &avila_npec_data,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static struct platform_device *avila_devices[] __initdata = {
|
||||||
|
&avila_i2c_gpio,
|
||||||
|
&avila_flash,
|
||||||
&avila_uart
|
&avila_uart
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,7 +72,6 @@
|
|||||||
+ platform_device_register(&avila_npec_device);
|
+ platform_device_register(&avila_npec_device);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+#ifdef CONFIG_SENSORS_EEPROM
|
|
||||||
+static void __init avila_gw2342_setup(void)
|
+static void __init avila_gw2342_setup(void)
|
||||||
+{
|
+{
|
||||||
+ platform_device_register(&avila_npeb_device);
|
+ platform_device_register(&avila_npeb_device);
|
||||||
@ -122,66 +150,57 @@
|
|||||||
+
|
+
|
||||||
+ for (i = 0; i < ARRAY_SIZE(avila_boards); i++) {
|
+ for (i = 0; i < ARRAY_SIZE(avila_boards); i++) {
|
||||||
+ struct avila_board_info *info = &avila_boards[i];
|
+ struct avila_board_info *info = &avila_boards[i];
|
||||||
+ if (strncmp(info->model, model, strlen(info->model)) == 0)
|
+ if (strcmp(info->model, model) == 0)
|
||||||
+ return info;
|
+ return info;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ return NULL;
|
+ return NULL;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+struct avila_eeprom_header {
|
+static struct at24_iface *at24_if;
|
||||||
+ unsigned char mac0[ETH_ALEN];
|
+
|
||||||
+ unsigned char mac1[ETH_ALEN];
|
+static int at24_setup(struct at24_iface *iface, void *context)
|
||||||
+ unsigned char res0[4];
|
+{
|
||||||
+ unsigned char magic[2];
|
+ char mac_addr[ETH_ALEN];
|
||||||
+ unsigned char config[14];
|
+ char model[6];
|
||||||
+ unsigned char model[16];
|
+
|
||||||
|
+ at24_if = iface;
|
||||||
|
+
|
||||||
|
+ /* Read MAC addresses */
|
||||||
|
+ if (at24_if->read(at24_if, mac_addr, 0x0, 6) == 6) {
|
||||||
|
+ memcpy(&avila_npeb_data.hwaddr, mac_addr, ETH_ALEN);
|
||||||
|
+ }
|
||||||
|
+ if (at24_if->read(at24_if, mac_addr, 0x6, 6) == 6) {
|
||||||
|
+ memcpy(&avila_npec_data.hwaddr, mac_addr, ETH_ALEN);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Read the first 6 bytes of the model number */
|
||||||
|
+ if (at24_if->read(at24_if, model, 0x20, 6) == 6) {
|
||||||
|
+ avila_info = avila_find_board_info(model);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct at24_platform_data avila_eeprom_info = {
|
||||||
|
+ .byte_len = 1024,
|
||||||
|
+ .page_size = 16,
|
||||||
|
+ .flags = AT24_FLAG_READONLY,
|
||||||
|
+ .setup = at24_setup,
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static int __init avila_eeprom_notify(struct notifier_block *self,
|
+static struct i2c_board_info __initdata avila_i2c_board_info[] = {
|
||||||
+ unsigned long event, void *t)
|
+/* {
|
||||||
+{
|
+ I2C_BOARD_INFO("rtc-ds1672", 0x68),
|
||||||
+ struct eeprom_data *ee = t;
|
+ },*/
|
||||||
+ struct avila_eeprom_header hdr;
|
+ {
|
||||||
+
|
+ I2C_BOARD_INFO("ad7418", 0x28),
|
||||||
+ if (avila_info)
|
+ },
|
||||||
+ return NOTIFY_DONE;
|
+ {
|
||||||
+
|
+ I2C_BOARD_INFO("24c08", 0x51),
|
||||||
+ /* The eeprom is at address 0x51 */
|
+ .platform_data = &avila_eeprom_info
|
||||||
+ if (event != EEPROM_REGISTER || ee->client.addr != 0x51)
|
+ },
|
||||||
+ return NOTIFY_DONE;
|
|
||||||
+
|
|
||||||
+ ee->attr->read(&ee->client.dev.kobj, ee->attr, (char *)&hdr,
|
|
||||||
+ 0, sizeof(hdr));
|
|
||||||
+
|
|
||||||
+ if (hdr.magic[0] != 'G' || hdr.magic[1] != 'W')
|
|
||||||
+ return NOTIFY_DONE;
|
|
||||||
+
|
|
||||||
+ memcpy(&avila_npeb_data.hwaddr, hdr.mac0, ETH_ALEN);
|
|
||||||
+ memcpy(&avila_npec_data.hwaddr, hdr.mac1, ETH_ALEN);
|
|
||||||
+
|
|
||||||
+ avila_info = avila_find_board_info(hdr.model);
|
|
||||||
+
|
|
||||||
+ return NOTIFY_OK;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct notifier_block avila_eeprom_notifier __initdata = {
|
|
||||||
+ .notifier_call = avila_eeprom_notify
|
|
||||||
+};
|
+};
|
||||||
+
|
|
||||||
+static void __init avila_register_eeprom_notifier(void)
|
|
||||||
+{
|
|
||||||
+ register_eeprom_notifier(&avila_eeprom_notifier);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void __init avila_unregister_eeprom_notifier(void)
|
|
||||||
+{
|
|
||||||
+ unregister_eeprom_notifier(&avila_eeprom_notifier);
|
|
||||||
+}
|
|
||||||
+#else /* CONFIG_SENSORS_EEPROM */
|
|
||||||
+static inline void avila_register_eeprom_notifier(void) {};
|
|
||||||
+static inline void avila_unregister_eeprom_notifier(void) {};
|
|
||||||
+#endif /* CONFIG_SENSORS_EEPROM */
|
|
||||||
+
|
+
|
||||||
static void __init avila_init(void)
|
static void __init avila_init(void)
|
||||||
{
|
{
|
||||||
@ -194,13 +213,12 @@
|
|||||||
avila_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
|
avila_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
|
||||||
avila_flash_resource.end =
|
avila_flash_resource.end =
|
||||||
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
|
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
|
||||||
@@ -184,9 +349,28 @@ static void __init avila_init(void)
|
@@ -159,7 +337,28 @@ static void __init avila_init(void)
|
||||||
|
|
||||||
platform_device_register(&avila_pata);
|
platform_device_register(&avila_pata);
|
||||||
|
|
||||||
- platform_device_register(avila_npeb_device);
|
+ i2c_register_board_info(0, avila_i2c_board_info,
|
||||||
- platform_device_register(avila_npec_device);
|
+ ARRAY_SIZE(avila_i2c_board_info));
|
||||||
+ avila_register_eeprom_notifier();
|
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int __init avila_model_setup(void)
|
+static int __init avila_model_setup(void)
|
||||||
@ -218,7 +236,6 @@
|
|||||||
+ avila_gw23xx_setup();
|
+ avila_gw23xx_setup();
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ avila_unregister_eeprom_notifier();
|
|
||||||
+ return 0;
|
+ return 0;
|
||||||
}
|
}
|
||||||
+late_initcall(avila_model_setup);
|
+late_initcall(avila_model_setup);
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
||||||
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
||||||
@@ -26,6 +26,7 @@
|
@@ -24,6 +24,7 @@
|
||||||
# include <linux/eeprom.h>
|
#include <linux/i2c.h>
|
||||||
#endif
|
#include <linux/i2c/at24.h>
|
||||||
|
|
||||||
+#include <linux/leds.h>
|
+#include <linux/leds.h>
|
||||||
#include <linux/i2c-gpio.h>
|
#include <linux/i2c-gpio.h>
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
@@ -172,6 +173,72 @@ static struct platform_device avila_npec
|
@@ -170,6 +171,72 @@ static struct platform_device avila_npec
|
||||||
.dev.platform_data = &avila_npec_data,
|
.dev.platform_data = &avila_npec_data,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,7 +81,7 @@
|
|||||||
static struct platform_device *avila_devices[] __initdata = {
|
static struct platform_device *avila_devices[] __initdata = {
|
||||||
&avila_i2c_gpio,
|
&avila_i2c_gpio,
|
||||||
&avila_flash,
|
&avila_flash,
|
||||||
@@ -182,6 +249,8 @@ static void __init avila_gw23xx_setup(vo
|
@@ -180,12 +247,16 @@ static void __init avila_gw23xx_setup(vo
|
||||||
{
|
{
|
||||||
platform_device_register(&avila_npeb_device);
|
platform_device_register(&avila_npeb_device);
|
||||||
platform_device_register(&avila_npec_device);
|
platform_device_register(&avila_npec_device);
|
||||||
@ -89,8 +89,7 @@
|
|||||||
+ platform_device_register(&avila_gpio_leds_device);
|
+ platform_device_register(&avila_gpio_leds_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SENSORS_EEPROM
|
static void __init avila_gw2342_setup(void)
|
||||||
@@ -189,6 +258,8 @@ static void __init avila_gw2342_setup(vo
|
|
||||||
{
|
{
|
||||||
platform_device_register(&avila_npeb_device);
|
platform_device_register(&avila_npeb_device);
|
||||||
platform_device_register(&avila_npec_device);
|
platform_device_register(&avila_npec_device);
|
||||||
@ -99,7 +98,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void __init avila_gw2345_setup(void)
|
static void __init avila_gw2345_setup(void)
|
||||||
@@ -199,22 +270,30 @@ static void __init avila_gw2345_setup(vo
|
@@ -196,22 +267,30 @@ static void __init avila_gw2345_setup(vo
|
||||||
|
|
||||||
avila_npec_data.phy = 5; /* port 5 of the KS8995 switch */
|
avila_npec_data.phy = 5; /* port 5 of the KS8995 switch */
|
||||||
platform_device_register(&avila_npec_device);
|
platform_device_register(&avila_npec_device);
|
||||||
@ -130,7 +129,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void __init avila_gw2355_setup(void)
|
static void __init avila_gw2355_setup(void)
|
||||||
@@ -225,11 +304,29 @@ static void __init avila_gw2355_setup(vo
|
@@ -222,11 +301,29 @@ static void __init avila_gw2355_setup(vo
|
||||||
|
|
||||||
avila_npec_data.phy = 16;
|
avila_npec_data.phy = 16;
|
||||||
platform_device_register(&avila_npec_device);
|
platform_device_register(&avila_npec_device);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
||||||
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
||||||
@@ -239,10 +239,28 @@ static struct platform_device avila_latc
|
@@ -237,10 +237,28 @@ static struct platform_device avila_latc
|
||||||
.dev.platform_data = &avila_latch_leds_data,
|
.dev.platform_data = &avila_latch_leds_data,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
--- a/arch/arm/mach-ixp4xx/avila-setup.c
|
||||||
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
|
||||||
@@ -294,6 +294,7 @@ static void __init avila_gw2345_setup(vo
|
@@ -291,6 +291,7 @@ static void __init avila_gw2345_setup(vo
|
||||||
|
|
||||||
static void __init avila_gw2347_setup(void)
|
static void __init avila_gw2347_setup(void)
|
||||||
{
|
{
|
||||||
@ -8,7 +8,7 @@
|
|||||||
platform_device_register(&avila_npeb_device);
|
platform_device_register(&avila_npeb_device);
|
||||||
|
|
||||||
avila_gpio_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO;
|
avila_gpio_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO;
|
||||||
@@ -338,6 +339,7 @@ static void __init avila_gw2355_setup(vo
|
@@ -335,6 +336,7 @@ static void __init avila_gw2355_setup(vo
|
||||||
|
|
||||||
static void __init avila_gw2357_setup(void)
|
static void __init avila_gw2357_setup(void)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user