* Re: [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code to supportRev B boards
From: Sean MacLennan @ 2008-04-29 3:28 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev, Stephen Rothwell
In-Reply-To: <20080428214711.240419c3@lappy.seanm.ca>
A change to the dts to get gpios correct broke the led code.
PIKA Warp: Update platform code to support Rev B boards.
* Switched from 64M NOR/64M NAND to 4M NOR/256M NAND.
* Full DTM support including critical temperature.
* Added POST information.
* Removed LED function, moved to new LED driver.
* Moved ad7414 to new style I2C initialization.
Signed-off-by: Sean MacLennan <smaclennan@pikatech.com>
diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c
index eb108a8..2178021 100644
--- a/arch/powerpc/boot/cuboot-warp.c
+++ b/arch/powerpc/boot/cuboot-warp.c
@@ -10,6 +10,7 @@
#include "ops.h"
#include "4xx.h"
#include "cuboot.h"
+#include "stdio.h"
#define TARGET_4xx
#define TARGET_44x
@@ -17,14 +18,54 @@
static bd_t bd;
-static void warp_fixups(void)
+static void warp_fixup_one_nor(u32 from, u32 to)
{
- unsigned long sysclk = 66000000;
+ void *devp;
+ char name[50];
+ u32 v[2];
+
+ sprintf(name, "/plb/opb/ebc/nor_flash@0,0/partition@%x", from);
+
+ devp = finddevice(name);
+ if (!devp)
+ return;
+
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[0] = to;
+ setprop(devp, "reg", v, sizeof(v));
+
+ printf("NOR 64M fixup %x -> %x\r\n", from, to);
+ }
+}
+
- ibm440ep_fixup_clocks(sysclk, 11059200, 50000000);
+static void warp_fixups(void)
+{
+ ibm440ep_fixup_clocks(66000000, 11059200, 50000000);
ibm4xx_sdram_fixup_memsize();
ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+
+ /* Fixup for 64M flash on Rev A boards. */
+ if (bd.bi_flashsize == 0x4000000) {
+ void *devp;
+ u32 v[3];
+
+ devp = finddevice("/plb/opb/ebc/nor_flash@0,0");
+ if (!devp)
+ return;
+
+ /* Fixup the size */
+ if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) {
+ v[2] = bd.bi_flashsize;
+ setprop(devp, "reg", v, sizeof(v));
+ }
+
+ /* Fixup parition offsets */
+ warp_fixup_one_nor(0x300000, 0x3f00000);
+ warp_fixup_one_nor(0x340000, 0x3f40000);
+ warp_fixup_one_nor(0x380000, 0x3f80000);
+ }
}
diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c
index 9150318..d293c70 100644
--- a/arch/powerpc/platforms/44x/warp-nand.c
+++ b/arch/powerpc/platforms/44x/warp-nand.c
@@ -11,8 +11,10 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/ndfc.h>
+#include <linux/of.h>
#include <asm/machdep.h>
+
#ifdef CONFIG_MTD_NAND_NDFC
#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
@@ -35,13 +37,23 @@ static struct mtd_partition nand_parts[] = {
{
.name = "root",
.offset = 0x0200000,
- .size = 0x3400000
+ .size = 0x3E00000
+ },
+ {
+ .name = "persistent",
+ .offset = 0x4000000,
+ .size = 0x4000000
},
{
- .name = "user",
- .offset = 0x3600000,
- .size = 0x0A00000
+ .name = "persistent1",
+ .offset = 0x8000000,
+ .size = 0x4000000
},
+ {
+ .name = "persistent2",
+ .offset = 0xC000000,
+ .size = 0x4000000
+ }
};
struct ndfc_controller_settings warp_ndfc_settings = {
@@ -67,19 +79,15 @@ static struct platform_device warp_ndfc_device = {
.resource = &warp_ndfc,
};
-static struct nand_ecclayout nand_oob_16 = {
- .eccbytes = 3,
- .eccpos = { 0, 1, 2, 3, 6, 7 },
- .oobfree = { {.offset = 8, .length = 16} }
-};
-
+/* Do NOT set the ecclayout: let it default so it is correct for both
+ * 64M and 256M flash chips.
+ */
static struct platform_nand_chip warp_nand_chip0 = {
.nr_chips = 1,
.chip_offset = CS_NAND_0,
.nr_partitions = ARRAY_SIZE(nand_parts),
.partitions = nand_parts,
- .chip_delay = 50,
- .ecclayout = &nand_oob_16,
+ .chip_delay = 20,
.priv = &warp_chip0_settings,
};
@@ -96,6 +104,23 @@ static struct platform_device warp_nand_device = {
static int warp_setup_nand_flash(void)
{
+ struct device_node *np;
+
+ /* Try to detect a rev A based on NOR size. */
+ np = of_find_compatible_node(NULL, NULL, "cfi-flash");
+ if (np) {
+ struct property *pp;
+
+ pp = of_find_property(np, "reg", NULL);
+ if (pp && (pp->length == 12)) {
+ u32 *v = pp->value;
+ if (v[2] == 0x4000000)
+ /* Rev A = 64M NAND */
+ warp_nand_chip0.nr_partitions = 2;
+ }
+ of_node_put(np);
+ }
+
platform_device_register(&warp_ndfc_device);
platform_device_register(&warp_nand_device);
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 39cf615..318f859 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -12,6 +12,10 @@
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/kthread.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pika.h>
+#include <linux/delay.h>
#include <asm/machdep.h>
#include <asm/prom.h>
@@ -27,6 +31,18 @@ static __initdata struct of_device_id warp_of_bus[] = {
{},
};
+static __initdata struct i2c_board_info warp_i2c_info[] = {
+ { I2C_BOARD_INFO("ad7414", 0x4a) }
+};
+
+static int __init warp_arch_init(void)
+{
+ /* This should go away once support is moved to the dts. */
+ i2c_register_board_info(0, warp_i2c_info, ARRAY_SIZE(warp_i2c_info));
+ return 0;
+}
+machine_arch_initcall(warp, warp_arch_init);
+
static int __init warp_device_probe(void)
{
of_platform_bus_probe(NULL, warp_of_bus, NULL);
@@ -52,61 +68,232 @@ define_machine(warp) {
};
-#define LED_GREEN (0x80000000 >> 0)
-#define LED_RED (0x80000000 >> 1)
+/* I am not sure this is the best place for this... */
+static int __init warp_post_info(void)
+{
+ struct device_node *np;
+ void __iomem *fpga;
+ u32 post1, post2;
+
+ /* Sighhhh... POST information is in the sd area. */
+ np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
+ if (np == NULL)
+ return -ENOENT;
+
+ fpga = of_iomap(np, 0);
+ of_node_put(np);
+ if (fpga == NULL)
+ return -ENOENT;
+
+ post1 = in_be32(fpga + 0x40);
+ post2 = in_be32(fpga + 0x44);
+
+ iounmap(fpga);
+
+ if (post1 || post2)
+ printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
+ else
+ printk(KERN_INFO "Warp POST OK\n");
+
+ return 0;
+}
+machine_late_initcall(warp, warp_post_info);
+
+
+#ifdef CONFIG_SENSORS_AD7414
+
+static LIST_HEAD(dtm_shutdown_list);
+static void __iomem *dtm_fpga;
+static void __iomem *gpio_base;
+
+
+struct dtm_shutdown {
+ struct list_head list;
+ void (*func)(void *arg);
+ void *arg;
+};
-/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */
-void warp_set_power_leds(int green, int red)
+int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
{
- static void __iomem *gpio_base = NULL;
- unsigned leds;
-
- if (gpio_base == NULL) {
- struct device_node *np;
-
- /* Power LEDS are on the second GPIO controller */
- np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
- if (np)
- np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP");
- if (np == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
- return;
+ struct dtm_shutdown *shutdown;
+
+ shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL);
+ if (shutdown == NULL)
+ return -ENOMEM;
+
+ shutdown->func = func;
+ shutdown->arg = arg;
+
+ list_add(&shutdown->list, &dtm_shutdown_list);
+
+ return 0;
+}
+
+int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ struct dtm_shutdown *shutdown;
+
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ if (shutdown->func == func && shutdown->arg == arg) {
+ list_del(&shutdown->list);
+ kfree(shutdown);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static irqreturn_t temp_isr(int irq, void *context)
+{
+ struct dtm_shutdown *shutdown;
+
+ local_irq_disable();
+
+ /* Run through the shutdown list. */
+ list_for_each_entry(shutdown, &dtm_shutdown_list, list)
+ shutdown->func(shutdown->arg);
+
+ printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
+
+ while (1) {
+ if (dtm_fpga) {
+ unsigned reset = in_be32(dtm_fpga + 0x14);
+ out_be32(dtm_fpga + 0x14, reset);
}
- gpio_base = of_iomap(np, 0);
- of_node_put(np);
- if (gpio_base == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to map gpio");
- return;
+ if (gpio_base) {
+ unsigned leds = in_be32(gpio_base);
+
+ /* green off, red toggle */
+ leds &= ~0x80000000;
+ leds ^= 0x40000000;
+
+ out_be32(gpio_base, leds);
}
+
+ mdelay(500);
+ }
+}
+
+static int pika_setup_leds(void)
+{
+ struct device_node *np;
+ const u32 *gpios;
+ int len;
+
+ np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
+ if (!np) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n");
+ return -ENOENT;
}
- leds = in_be32(gpio_base);
+ gpios = of_get_property(np, "gpios", &len);
+ of_node_put(np);
+ if (!gpios || len < 4) {
+ printk(KERN_ERR __FILE__
+ ": Unable to get gpios property (%d)\n", len);
+ return -ENOENT;
+ }
- switch (green) {
- case 0: leds &= ~LED_GREEN; break;
- case 1: leds |= LED_GREEN; break;
+ np = of_find_node_by_phandle(gpios[0]);
+ if (!np) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
+ return -ENOENT;
}
- switch (red) {
- case 0: leds &= ~LED_RED; break;
- case 1: leds |= LED_RED; break;
+
+ gpio_base = of_iomap(np, 0);
+ of_node_put(np);
+ if (!gpio_base) {
+ printk(KERN_ERR __FILE__ ": Unable to map gpio");
+ return -ENOMEM;
}
- out_be32(gpio_base, leds);
+ return 0;
}
-EXPORT_SYMBOL(warp_set_power_leds);
+static void pika_setup_critical_temp(struct i2c_client *client)
+{
+ struct device_node *np;
+ int irq, rc;
+
+ /* Do this before enabling critical temp interrupt since we
+ * may immediately interrupt.
+ */
+ pika_setup_leds();
+
+ /* These registers are in 1 degree increments. */
+ i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
+ i2c_smbus_write_byte_data(client, 3, 55); /* Tlow */
+
+ np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
+ if (np == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
+ return;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ of_node_put(np);
+ if (irq == NO_IRQ) {
+ printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
+ return;
+ }
+
+ rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
+ if (rc) {
+ printk(KERN_ERR __FILE__
+ ": Unable to request ad7414 irq %d = %d\n", irq, rc);
+ return;
+ }
+}
+
+static inline void pika_dtm_check_fan(void __iomem *fpga)
+{
+ static int fan_state;
+ u32 fan = in_be32(fpga + 0x34) & (1 << 14);
+
+ if (fan_state != fan) {
+ fan_state = fan;
+ if (fan)
+ printk(KERN_WARNING "Fan rotation error detected."
+ " Please check hardware.\n");
+ }
+}
-#ifdef CONFIG_SENSORS_AD7414
static int pika_dtm_thread(void __iomem *fpga)
{
- extern int ad7414_get_temp(int index);
+ struct i2c_adapter *adap;
+ struct i2c_client *client;
+
+ /* We loop in case either driver was compiled as a module and
+ * has not been insmoded yet.
+ */
+ while (!(adap = i2c_get_adapter(0))) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+ while (1) {
+ list_for_each_entry(client, &adap->clients, list)
+ if (client->addr == 0x4a)
+ goto found_it;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+found_it:
+ i2c_put_adapter(adap);
+
+ pika_setup_critical_temp(client);
+
+ printk(KERN_INFO "PIKA DTM thread running.\n");
while (!kthread_should_stop()) {
- int temp = ad7414_get_temp(0);
+ u16 temp = swab16(i2c_smbus_read_word_data(client, 0));
+ out_be32(fpga + 0x20, temp);
- out_be32(fpga, temp);
+ pika_dtm_check_fan(fpga);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
@@ -115,37 +302,44 @@ static int pika_dtm_thread(void __iomem *fpga)
return 0;
}
+
static int __init pika_dtm_start(void)
{
struct task_struct *dtm_thread;
struct device_node *np;
- struct resource res;
- void __iomem *fpga;
np = of_find_compatible_node(NULL, NULL, "pika,fpga");
if (np == NULL)
return -ENOENT;
- /* We do not call of_iomap here since it would map in the entire
- * fpga space, which is over 8k.
- */
- if (of_address_to_resource(np, 0, &res)) {
- of_node_put(np);
- return -ENOENT;
- }
+ dtm_fpga = of_iomap(np, 0);
of_node_put(np);
-
- fpga = ioremap(res.start, 0x24);
- if (fpga == NULL)
+ if (dtm_fpga == NULL)
return -ENOENT;
- dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm");
+ dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
if (IS_ERR(dtm_thread)) {
- iounmap(fpga);
+ iounmap(dtm_fpga);
return PTR_ERR(dtm_thread);
}
return 0;
}
-device_initcall(pika_dtm_start);
+machine_late_initcall(warp, pika_dtm_start);
+
+#else /* !CONFIG_SENSORS_AD7414 */
+
+int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
+int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
+{
+ return 0;
+}
+
#endif
+
+EXPORT_SYMBOL(pika_dtm_register_shutdown);
+EXPORT_SYMBOL(pika_dtm_unregister_shutdown);
^ permalink raw reply related
* RE: [PATCH v2] MSI driver for Freescale 83xx/85xx/86xx cpu
From: Jin Zhengxiong @ 2008-04-29 3:39 UTC (permalink / raw)
To: Gala Kumar; +Cc: linuxppc-dev
In-Reply-To: <65D1ED37-6B8D-436C-A994-E8764922FE6D@freescale.com>
=20
> -----Original Message-----
> From: Gala Kumar=20
> Sent: Tuesday, April 22, 2008 9:38 PM
> To: Jin Zhengxiong
> Cc: linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH v2] MSI driver for Freescale 83xx/85xx/86xx cpu
>=20
> > diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/=20
> > Makefile index 6d386d0..e60a238 100644
> > --- a/arch/powerpc/sysdev/Makefile
> > +++ b/arch/powerpc/sysdev/Makefile
> > @@ -4,6 +4,7 @@ endif
> >
> > mpic-msi-obj-$(CONFIG_PCI_MSI) +=3D mpic_msi.o mpic_u3msi.o =20
> > mpic_pasemi_msi.o
> > obj-$(CONFIG_MPIC) +=3D mpic.o $(mpic-msi-obj-y)
> > +obj-$(CONFIG_FSL_PCI) +=3D fsl_msi.o
>=20
> can we do something like:
> fsl_pci-$(CONFIG_MSI) +=3D fsl_msi.o
> obj-$(CONFIG_FSL_PCI) +=3D fsl_pci.o $(fsl_pci-y)
>=20
> > obj-$(CONFIG_PPC_MPC106) +=3D grackle.o
> > obj-$(CONFIG_PPC_DCR_NATIVE) +=3D dcr-low.o
OK, Thanks
>=20
> > +static int fsl_msi_init_allocator(struct fsl_msi *msi_data) {
> > + int rc, size;
> > +
> > + size =3D BITS_TO_LONGS(NR_MSI_IRQS) * sizeof(long);
>=20
> should this be long or u32?
>=20
> > +
> > + msi_data->fsl_msi_bitmap =3D kzalloc(size, GFP_KERNEL);
> > +
> > + if (msi_data->fsl_msi_bitmap =3D=3D NULL) {
> > + pr_debug("%s: ENOMEM allocating allocator bitmap!\n",
> > + __func__);
> > + return -ENOMEM;
> > + }
> > +
> > + rc =3D fsl_msi_free_dt_hwirqs(msi_data);
> > + if (rc)
> > + goto out_free;
> > +
> > + return 0;
> > +out_free:
> > + kfree(msi_data->fsl_msi_bitmap);
> > +
> > + msi_data->fsl_msi_bitmap =3D NULL;
> > + return rc;
> > +
> > +}
> > +
> > +static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int
> > type)
> > +{
> > + if (type =3D=3D PCI_CAP_ID_MSIX)
> > + pr_debug("fslmsi: MSI-X untested, trying anyway.\n");
> > +
> > + return 0;
> > +}
> > +
> > +static void fsl_teardown_msi_irqs(struct pci_dev *pdev) {
> > + struct msi_desc *entry;
> > + struct fsl_msi *msi_data =3D fsl_msi;
> > +
> > + list_for_each_entry(entry, &pdev->msi_list, list) {
> > + if (entry->irq =3D=3D NO_IRQ)
> > + continue;
> > + set_irq_msi(entry->irq, NULL);
> > + fsl_msi_free_hwirqs(msi_data,=20
> virq_to_hw(entry->irq), 1);
> > + irq_dispose_mapping(entry->irq);
> > + }
> > +
> > + return;
> > +}
> > +
> > +static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
> > + struct msi_msg *msg)
> > +{
> > + struct fsl_msi *msi_data =3D fsl_msi;
> > +
> > + msg->address_lo =3D msi_data->msi_addr_lo;
> > + msg->address_hi =3D msi_data->msi_addr_hi;
> > + msg->data =3D hwirq;
> > +
> > + pr_debug("%s: allocated srs: %d, ibs: %d\n",
> > + __func__, hwirq / INT_PER_MSIR, hwirq % INT_PER_MSIR); }
> > +
> > +static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int
> > type)
> > +{
> > + irq_hw_number_t hwirq;
> > + int rc;
> > + unsigned int virq;
> > + struct msi_desc *entry;
> > + struct msi_msg msg;
> > + struct fsl_msi *msi_data =3D fsl_msi;
> > +
> > + list_for_each_entry(entry, &pdev->msi_list, list) {
> > + hwirq =3D fsl_msi_alloc_hwirqs(msi_data, 1);
> > + if (hwirq < 0) {
> > + rc =3D hwirq;
> > + pr_debug("%s: fail allocating msi interrupt\n",
> > + __func__);
> > + goto out_free;
> > + }
> > +
> > + virq =3D irq_create_mapping(msi_data->irqhost, hwirq);
> > +
> > + if (virq =3D=3D NO_IRQ) {
> > + pr_debug("%s: fail mapping hwirq 0x%lx\n",
> > + __func__, hwirq);
> > + fsl_msi_free_hwirqs(msi_data, hwirq, 1);
> > + rc =3D -ENOSPC;
> > + goto out_free;
> > + }
> > + set_irq_msi(virq, entry);
> > +
> > + fsl_compose_msi_msg(pdev, hwirq, &msg);
> > + write_msi_msg(virq, &msg);
> > + }
> > + return 0;
> > +
> > +out_free:
> > + return rc;
> > +}
> > +
> > +void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) {
> > + unsigned int cascade_irq;
> > + struct fsl_msi *msi_data =3D fsl_msi;
> > + int msir_index =3D -1;
> > + u32 msir_value =3D 0;
> > + u32 intr_index;
> > + u32 have_shift =3D 0;
> > +
> > + spin_lock(&desc->lock);
> > + if ((msi_data->feature & FSL_PIC_IP_MASK) =3D=3D FSL_PIC_IP_IPIC) =
{
> > + if (desc->chip->mask_ack)
> > + desc->chip->mask_ack(irq);
> > + else {
> > + desc->chip->mask(irq);
> > + desc->chip->ack(irq);
> > + }
> > + }
> > +
> > + if (unlikely(desc->status & IRQ_INPROGRESS))
> > + goto unlock;
> > +
> > + msir_index =3D (int)(desc->handler_data);
> > +
> > + if (msir_index >=3D NR_MSIR)
> > + cascade_irq =3D NO_IRQ;
> > +
> > + desc->status |=3D IRQ_INPROGRESS;
> > + switch (fsl_msi->feature & FSL_PIC_IP_MASK) {
> > + case FSL_PIC_IP_MPIC:
> > + msir_value =3D fsl_msi_read(msi_data->msi_regs,
> > + msir_index * 0x10);
> > + break;
> > + case FSL_PIC_IP_IPIC:
> > + msir_value =3D fsl_msi_read(msi_data->msi_regs,=20
> msir_index * 0x4);
> > + break;
> > + }
> > +
> > + while (msir_value) {
> > + intr_index =3D ffs(msir_value) - 1;
> > +
> > + cascade_irq =3D irq_linear_revmap(msi_data->irqhost,
> > + (msir_index * INT_PER_MSIR + intr_index=20
> + have_shift));
> > +
> > + if (cascade_irq !=3D NO_IRQ)
> > + generic_handle_irq(cascade_irq);
> > + have_shift +=3D (intr_index + 1);
> > + msir_value =3D (msir_value >> (intr_index + 1));
> > + }
> > + desc->status &=3D ~IRQ_INPROGRESS;
> > +
> > + switch (msi_data->feature & FSL_PIC_IP_MASK) {
> > + case FSL_PIC_IP_MPIC:
> > + desc->chip->eoi(irq);
> > + break;
> > + case FSL_PIC_IP_IPIC:
> > + if (!(desc->status & IRQ_DISABLED) &&=20
> desc->chip->unmask)
> > + desc->chip->unmask(irq);
> > + break;
> > + }
> > +unlock:
> > + spin_unlock(&desc->lock);
> > +}
> > +
> > +static int __devinit fsl_of_msi_probe(struct of_device *dev,
> > + const struct of_device_id *match) {
> > + struct fsl_msi *msi;
> > + struct resource res;
> > + int err, i, count;
> > + int rc;
> > + int virt_msir;
> > + const u32 *p;
> > + struct fsl_msi_feature *tmp_data;
> > +
> > + printk(KERN_DEBUG "Setting up fsl msi support\n");
> > +
> > + msi =3D kzalloc(sizeof(struct fsl_msi), GFP_KERNEL);
> > + if (!msi) {
> > + dev_err(&dev->dev, "No memory for MSI structure\n");
> > + err =3D -ENOMEM;
> > + goto error_out;
> > + }
> > +
> > + msi->of_node =3D dev->node;
> > +
> > + msi->irqhost =3D irq_alloc_host(of_node_get(dev->node),
> > + IRQ_HOST_MAP_LINEAR,
> > + NR_MSI_IRQS, &fsl_msi_host_ops, 0);
> > + if (msi->irqhost =3D=3D NULL) {
> > + dev_err(&dev->dev, "No memory for MSI irqhost\n");
> > + of_node_put(dev->node);
> > + err =3D -ENOMEM;
> > + goto error_out;
> > + }
> > +
> > + /* Get the MSI reg base */
> > + err =3D of_address_to_resource(dev->node, 0, &res);
> > + if (err) {
> > + dev_err(&dev->dev, "%s resource error!\n",
> > + dev->node->full_name);
> > + goto error_out;
> > + }
> > +
> > + msi->msi_regs =3D ioremap(res.start, res.end - res.start + 1);
> > + if (!msi->msi_regs) {
> > + dev_err(&dev->dev, "ioremap problem failed\n");
> > + goto error_out;
> > + }
> > +
> > + tmp_data =3D (struct fsl_msi_feature *)match->data;
> > +
> > + msi->feature =3D tmp_data->fsl_pic_ip;
> > +
> > + msi->irqhost->host_data =3D msi;
> > +
> > + msi->msi_addr_hi =3D 0x0;
> > + msi->msi_addr_lo =3D res.start + tmp_data->msiir_offset;
> > +
> > + rc =3D fsl_msi_init_allocator(msi);
> > + if (rc) {
> > + dev_err(&dev->dev, "Error allocating MSI bitmap\n");
> > + goto error_out;
> > + }
> > +
> > + p =3D of_get_property(dev->node, "interrupts", &count);
> > + if (!p) {
> > + dev_err(&dev->dev, "no interrupts property=20
> found on %s\n",
> > + dev->node->full_name);
> > + err =3D -ENODEV;
> > + goto error_out;
> > + }
> > + if (count % 8 !=3D 0) {
> > + dev_err(&dev->dev, "Malformed interrupts=20
> property on %s\n",
> > + dev->node->full_name);
> > + err =3D -EINVAL;
> > + goto error_out;
> > + }
> > +
> > + count /=3D sizeof(u32);
> > + for (i =3D 0; i < count / 2; i++) {
> > + if (i > NR_MSIR)
> > + break;
> > + virt_msir =3D irq_of_parse_and_map(dev->node, i);
> > + if (virt_msir !=3D NO_IRQ) {
> > + set_irq_data(virt_msir, (void *)i);
> > + set_irq_chained_handler(virt_msir,=20
> fsl_msi_cascade);
> > + }
> > + }
> > +
> > + fsl_msi =3D msi;
> > +
> > + WARN_ON(ppc_md.setup_msi_irqs);
> > + ppc_md.setup_msi_irqs =3D fsl_setup_msi_irqs;
> > + ppc_md.teardown_msi_irqs =3D fsl_teardown_msi_irqs;
> > + ppc_md.msi_check_device =3D fsl_msi_check_device;
> > + return 0;
> > +error_out:
> > + kfree(msi);
> > + return err;
> > +}
> > +
> > +static const struct fsl_msi_feature mpic_msi_feature =3D
> > {FSL_PIC_IP_MPIC, 0x140};
> > +static const struct fsl_msi_feature ipic_msi_feature =3D
> > {FSL_PIC_IP_IPIC, 0x38};
>=20
> make this
> {
> .fsl_pic_ip =3D FSL_PIC_IP_MPIC
> .offset =3D 0x140
> };
>=20
> for readability.
>=20
OK!
> > +
> > +static const struct of_device_id fsl_of_msi_ids[] =3D {
> > + {
> > + .compatible =3D "fsl,MPIC-MSI",
> > + .data =3D (void *)&mpic_msi_feature,
> > + },
> > + {
> > + .compatible =3D "fsl,IPIC-MSI",
> > + .data =3D (void *)&ipic_msi_feature,
> > + },
> > + {}
> > +};
> > +
> > +static struct of_platform_driver fsl_of_msi_driver =3D {
> > + .name =3D "fsl-of-msi",
> > + .match_table =3D fsl_of_msi_ids,
> > + .probe =3D fsl_of_msi_probe,
> > +};
> > +
> > +static __init int fsl_of_msi_init(void) {
> > + return of_register_platform_driver(&fsl_of_msi_driver);
> > +}
> > +
> > +subsys_initcall(fsl_of_msi_init);
> > diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/=20
> > fsl_msi.h new file mode 100644 index 0000000..628b6c0
> > --- /dev/null
> > +++ b/arch/powerpc/sysdev/fsl_msi.h
> > @@ -0,0 +1,36 @@
> > +#ifndef _POWERPC_SYSDEV_FSL_MSI_H
> > +#define _POWERPC_SYSDEV_FSL_MSI_H
> > +
> > +#define NR_MSIR 8
>=20
> NR_MSR_REG
>=20
> > +#define INT_PER_MSIR 32
>=20
> IRQS_PER_MSI_REG
>=20
> >
> > +#define NR_MSI_IRQS (NR_MSIR * INT_PER_MSIR)
> > +
> > +#define FSL_PIC_IP_MASK 0x0000000F
> > +#define FSL_PIC_IP_MPIC 0x00000001
> > +#define FSL_PIC_IP_IPIC 0x00000002
> > +
> > +struct fsl_msi {
> > + /* Device node of the MSI interrupt*/
> > + struct device_node *of_node;
> > +
> > + struct irq_host *irqhost;
> > +
> > + unsigned long cascade_irq;
> > +
> > + u32 msi_addr_lo;
> > + u32 msi_addr_hi;
> > + void __iomem *msi_regs;
> > + u32 feature;
> > +
> > + unsigned long *fsl_msi_bitmap;
> > + spinlock_t bitmap_lock;
> > + const char *name;
> > +};
> > +
> > +struct fsl_msi_feature {
> > + u32 fsl_pic_ip;
> > + u32 msiir_offset;
> > +};
>=20
> move this struct into .c
OK
> >
> > +
> > +#endif /* _POWERPC_SYSDEV_FSL_MSI_H */
> > +
> > diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/=20
> > fsl_pci.c index bf13c21..fede767 100644
> > --- a/arch/powerpc/sysdev/fsl_pci.c
> > +++ b/arch/powerpc/sysdev/fsl_pci.c
> > @@ -106,6 +106,16 @@ void __init setup_pci_cmd(struct pci_controller
> > *hose)
> > }
> > }
> >
> > +#ifdef CONFIG_PCI_MSI
> > +void __init setup_pci_pcsrbar(struct pci_controller *hose) {
> > + phys_addr_t immr_base;
> > +
> > + immr_base =3D get_immrbase();
> > + early_write_config_dword(hose, 0, 0,=20
> PCI_BASE_ADDRESS_0, immr_base);=20
> > +} #endif
> > +
> > static int fsl_pcie_bus_fixup;
> >
> > static void __init quirk_fsl_pcie_header(struct pci_dev *dev) @@=20
> > -211,6 +221,10 @@ int __init fsl_add_bridge(struct=20
> device_node *dev,=20
> > int is_primary)
> > /* Setup PEX window registers */
> > setup_pci_atmu(hose, &rsrc);
> >
> > + /*Setup PEXCSRBAR */
> > +#ifdef CONFIG_PCI_MSI
> > + setup_pci_pcsrbar(hose);
> > +#endif
>=20
> I'm not convinced this is safe. we need to be careful to=20
> make sure the pcsrbar doesn't overlap with any other device.
>=20
The PCI MEM inbound/outband map seems 'one-one map' in our system and=20
the dts may guard the outband space not overlap(No one wish to set the
space
the same as immrbase :) ). =20
But the 2G inbound MEM was set in our system directly, So far the
pcsrbar is=20
not overlap with other device.
Thanks
Jason
=20
^ permalink raw reply
* Re: [PATCH 1/7] Implement arch disable/enable irq hooks.
From: Paul Mackerras @ 2008-04-29 4:44 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Guennadi Liakhovetski
In-Reply-To: <20080428203322.GD15223@ld0162-tx32.am.freescale.net>
Scott Wood writes:
> On Fri, Apr 25, 2008 at 02:57:24PM +0200, Guennadi Liakhovetski wrote:
> > is there any specific reason, why out of these 7 patches only the first
> > one made it into the mainline? AFAICS, there has been only one comment,
> > suggesting to replace printk with dev_err on two occasions in one of
> > the patches...
>
> A while ago Paul said on IRC he'd prefer to do the TLF_SLEEPING hack more
> like the soft IRQ disabling that 64-bit uses. I haven't yet had a chance
> to look into it, so the patch collects dust, despite the current
> implementation of TLF_SLEEPING working just fine.
I have taken a closer look at the TLF_SLEEPING patch and crystallized
my thoughts about it a bit:
1. Too many ifdefs - it's only a few instructions extra, so if we're
going to have the TLF_SLEEPING stuff we might as well have it
unconditionally.
2. It seems convoluted to me to go through transfer_to_handler_cont
and ret_from_except when we could just get out directly through
fast_exception_return, given that we are not calling a handler. The
only thing to watch out for there is that r7 and r8 haven't been
modified (or have been restored if they have).
3. The style in all the assembly code is not to have spaces after
commas separating instruction operands.
The untested patch below is what I was thinking of. If you'd like to
try it out, I'd be interested to hear how it goes.
Paul.
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 84c8686..162500f 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -146,6 +146,7 @@ transfer_to_handler:
lwz r12,TI_LOCAL_FLAGS(r9)
mtcrf 0x01,r12
bt- 31-TLF_NAPPING,4f
+ bt- 31-TLF_SLEEPING,7f
#endif /* CONFIG_6xx */
.globl transfer_to_handler_cont
transfer_to_handler_cont:
@@ -163,6 +164,13 @@ transfer_to_handler_cont:
4: rlwinm r12,r12,0,~_TLF_NAPPING
stw r12,TI_LOCAL_FLAGS(r9)
b power_save_6xx_restore
+
+7: rlwinm r12,r12,0,~TLF_SLEEPING
+ stw r12,TI_LOCAL_FLAGS(r9)
+ lwz r9,_MSR(r11) /* if sleeping, clear MSR.EE */
+ rlwinm r9,r9,0,~MSR_EE
+ lwz r12,_LINK(r11) /* and return to address in LR */
+ b fast_exception_return
#endif
/*
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index d030f5c..1cd8c8f 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -147,8 +147,10 @@ static inline struct thread_info *current_thread_info(void)
/* Bits in local_flags */
/* Don't move TLF_NAPPING without adjusting the code in entry_32.S */
#define TLF_NAPPING 0 /* idle thread enabled NAP mode */
+#define TLF_SLEEPING 1 /* suspend code enabled SLEEP mode */
#define _TLF_NAPPING (1 << TLF_NAPPING)
+#define _TLF_SLEEPING (1 << TLF_SLEEPING)
#endif /* __KERNEL__ */
^ permalink raw reply related
* Re: [PATCH 1/7] Implement arch disable/enable irq hooks.
From: Paul Mackerras @ 2008-04-29 5:04 UTC (permalink / raw)
To: Scott Wood, Guennadi Liakhovetski, linuxppc-dev
In-Reply-To: <18454.42926.213374.977098@cargo.ozlabs.ibm.com>
I wrote:
> +7: rlwinm r12,r12,0,~TLF_SLEEPING
That should be rlwinm r12,r12,0,~_TLF_SLEEPING (with the leading
underscore), of course. Thanks to Stephen Rothwell for pointing that
out.
Paul.
^ permalink raw reply
* Re: [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code to supportRev B boards
From: Paul Mackerras @ 2008-04-29 5:08 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev, Sean MacLennan, Stephen Rothwell
In-Reply-To: <20080428232855.22c13830@lappy.seanm.ca>
It doesn't help that both of these patches have the same subject line,
nor that it starts with "Re:". :(
Also, I find the statement "A change to the dts to get gpios correct
broke the led code" a bit opaque. It doesn't tell me in what way it
was broken or what this patch does to correct, or even what the change
was in enough detail that I could find the change in the git
repository.
Paul.
^ permalink raw reply
* [PATCH] [POWERPC] Add struct iommu_table argument to iommu_map_sg()
From: Mark Nelson @ 2008-04-29 5:17 UTC (permalink / raw)
To: PowerPC dev list; +Cc: fujita.tomonori
Make iommu_map_sg take a struct iommu_table. It did so before commit
740c3ce66700640a6e6136ff679b067e92125794 (iommu sg merging: ppc: make
iommu respect the segment size limits).
This stops the function looking in the archdata.dma_data for the iommu
table because in the future it will be called with a device that has
no table there.
This also has the nice side effect of making iommu_map_sg() match the
other map functions.
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
arch/powerpc/kernel/dma_64.c | 2 +-
arch/powerpc/kernel/iommu.c | 7 +++----
include/asm-powerpc/iommu.h | 6 +++---
3 files changed, 7 insertions(+), 8 deletions(-)
Index: upstream/arch/powerpc/kernel/dma_64.c
===================================================================
--- upstream.orig/arch/powerpc/kernel/dma_64.c
+++ upstream/arch/powerpc/kernel/dma_64.c
@@ -68,7 +68,7 @@ static void dma_iommu_unmap_single(struc
static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
int nelems, enum dma_data_direction direction)
{
- return iommu_map_sg(dev, sglist, nelems,
+ return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems,
device_to_mask(dev), direction);
}
Index: upstream/arch/powerpc/kernel/iommu.c
===================================================================
--- upstream.orig/arch/powerpc/kernel/iommu.c
+++ upstream/arch/powerpc/kernel/iommu.c
@@ -267,11 +267,10 @@ static void iommu_free(struct iommu_tabl
spin_unlock_irqrestore(&(tbl->it_lock), flags);
}
-int iommu_map_sg(struct device *dev, struct scatterlist *sglist,
- int nelems, unsigned long mask,
- enum dma_data_direction direction)
+int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
+ struct scatterlist *sglist, int nelems,
+ unsigned long mask, enum dma_data_direction direction)
{
- struct iommu_table *tbl = dev->archdata.dma_data;
dma_addr_t dma_next = 0, dma_addr;
unsigned long flags;
struct scatterlist *s, *outs, *segstart;
Index: upstream/include/asm-powerpc/iommu.h
===================================================================
--- upstream.orig/include/asm-powerpc/iommu.h
+++ upstream/include/asm-powerpc/iommu.h
@@ -79,9 +79,9 @@ extern void iommu_free_table(struct iomm
extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
int nid);
-extern int iommu_map_sg(struct device *dev, struct scatterlist *sglist,
- int nelems, unsigned long mask,
- enum dma_data_direction direction);
+extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
+ struct scatterlist *sglist, int nelems,
+ unsigned long mask, enum dma_data_direction direction);
extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
int nelems, enum dma_data_direction direction);
^ permalink raw reply
* HAVE_CONFIG
From: David H. Lynch Jr. @ 2008-04-29 5:34 UTC (permalink / raw)
To: linuxppc-embedded
Why does CONFIG_PPC set CONFIG_HAVE_IDE ?
--
Dave Lynch DLA Systems
Software Development: Embedded Linux
717.627.3770 dhlii@dlasys.net http://www.dlasys.net
fax: 1.253.369.9244 Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too numerous to list.
"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction."
Albert Einstein
^ permalink raw reply
* [PATCH] windfarm: add PowerMac 12,1 support
From: Benjamin Herrenschmidt @ 2008-04-29 5:39 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 32653 bytes --]
From: Etienne Bersac <bersace@gmail.com>
Implement a new driver named windfarm_pm121 which drive fans on PowerMac
12,1 machine : iMac G5 iSight (rev C) 17" and 20". It's based on
windfarm_pm81 driver from Benjamin Herrenschmidt.
Signed-off-by: Etienne Bersac <bersace@gmail.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Initial patch by Etienne, fixes by David, but they couldn't be
bothered making that a single patch for merging so here it is.
(Etienne, the accent on your name didn't survive the process sorry)
arch/powerpc/configs/g5_defconfig | 1
drivers/macintosh/Kconfig | 8
drivers/macintosh/Makefile | 5
drivers/macintosh/windfarm_lm75_sensor.c | 6
drivers/macintosh/windfarm_max6690_sensor.c | 20
drivers/macintosh/windfarm_pm121.c | 1040 ++++++++++++++++++++++++++++
drivers/macintosh/windfarm_smu_controls.c | 4
7 files changed, 1078 insertions(+), 6 deletions(-)
--- linux-work.orig/arch/powerpc/configs/g5_defconfig 2008-04-22 10:15:29.000000000 +1000
+++ linux-work/arch/powerpc/configs/g5_defconfig 2008-04-29 15:32:50.000000000 +1000
@@ -696,6 +696,7 @@ CONFIG_WINDFARM=y
CONFIG_WINDFARM_PM81=y
CONFIG_WINDFARM_PM91=y
CONFIG_WINDFARM_PM112=y
+CONFIG_WINDFARM_PM121=y
# CONFIG_PMAC_RACKMETER is not set
CONFIG_NETDEVICES=y
# CONFIG_NETDEVICES_MULTIQUEUE is not set
Index: linux-work/drivers/macintosh/Kconfig
===================================================================
--- linux-work.orig/drivers/macintosh/Kconfig 2008-03-03 11:58:43.000000000 +1100
+++ linux-work/drivers/macintosh/Kconfig 2008-04-29 15:32:50.000000000 +1000
@@ -234,6 +234,14 @@ config WINDFARM_PM112
which are the recent dual and quad G5 machines using the
970MP dual-core processor.
+config WINDFARM_PM121
+ tristate "Support for thermal management on PowerMac12,1"
+ depends on WINDFARM && I2C && PMAC_SMU
+ select I2C_POWERMAC
+ help
+ This driver provides thermal control for the PowerMac12,1
+ which is the iMac G5 (iSight)
+
config ANSLCD
tristate "Support for ANS LCD display"
depends on ADB_CUDA && PPC_PMAC
Index: linux-work/drivers/macintosh/Makefile
===================================================================
--- linux-work.orig/drivers/macintosh/Makefile 2007-09-28 11:42:07.000000000 +1000
+++ linux-work/drivers/macintosh/Makefile 2008-04-29 15:32:50.000000000 +1000
@@ -42,4 +42,9 @@ obj-$(CONFIG_WINDFARM_PM112) += windfarm
windfarm_smu_sensors.o \
windfarm_max6690_sensor.o \
windfarm_lm75_sensor.o windfarm_pid.o
+obj-$(CONFIG_WINDFARM_PM121) += windfarm_pm121.o windfarm_smu_sat.o \
+ windfarm_smu_controls.o \
+ windfarm_smu_sensors.o \
+ windfarm_max6690_sensor.o \
+ windfarm_lm75_sensor.o windfarm_pid.o
obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o
Index: linux-work/drivers/macintosh/windfarm_lm75_sensor.c
===================================================================
--- linux-work.orig/drivers/macintosh/windfarm_lm75_sensor.c 2007-09-28 11:42:07.000000000 +1000
+++ linux-work/drivers/macintosh/windfarm_lm75_sensor.c 2008-04-29 15:32:50.000000000 +1000
@@ -127,6 +127,12 @@ static struct wf_lm75_sensor *wf_lm75_cr
*/
if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
lm->sens.name = "hd-temp";
+ else if (!strcmp(loc, "Incoming Air Temp"))
+ lm->sens.name = "incoming-air-temp";
+ else if (!strcmp(loc, "ODD Temp"))
+ lm->sens.name = "optical-drive-temp";
+ else if (!strcmp(loc, "HD Temp"))
+ lm->sens.name = "hard-drive-temp";
else
goto fail;
Index: linux-work/drivers/macintosh/windfarm_max6690_sensor.c
===================================================================
--- linux-work.orig/drivers/macintosh/windfarm_max6690_sensor.c 2007-09-28 11:42:07.000000000 +1000
+++ linux-work/drivers/macintosh/windfarm_max6690_sensor.c 2008-04-29 15:32:50.000000000 +1000
@@ -77,18 +77,28 @@ static struct wf_sensor_ops wf_max6690_o
.owner = THIS_MODULE,
};
-static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr)
+static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
+ const char *loc)
{
struct wf_6690_sensor *max;
- char *name = "backside-temp";
+ char *name;
max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
if (max == NULL) {
printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
- "no memory\n", name);
+ "no memory\n", loc);
return;
}
+ if (!strcmp(loc, "BACKSIDE"))
+ name = "backside-temp";
+ else if (!strcmp(loc, "NB Ambient"))
+ name = "north-bridge-temp";
+ else if (!strcmp(loc, "GPU Ambient"))
+ name = "gpu-temp";
+ else
+ goto fail;
+
max->sens.ops = &wf_max6690_ops;
max->sens.name = name;
max->i2c.addr = addr >> 1;
@@ -138,9 +148,7 @@ static int wf_max6690_attach(struct i2c_
if (loc == NULL || addr == 0)
continue;
printk("found max6690, loc=%s addr=0x%02x\n", loc, addr);
- if (strcmp(loc, "BACKSIDE"))
- continue;
- wf_max6690_create(adapter, addr);
+ wf_max6690_create(adapter, addr, loc);
}
return 0;
Index: linux-work/drivers/macintosh/windfarm_pm121.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/drivers/macintosh/windfarm_pm121.c 2008-04-29 15:32:58.000000000 +1000
@@ -0,0 +1,1040 @@
+/*
+ * Windfarm PowerMac thermal control. iMac G5 iSight
+ *
+ * (c) Copyright 2007 Étienne Bersac <bersace@gmail.com>
+ *
+ * Bits & pieces from windfarm_pm81.c by (c) Copyright 2005 Benjamin
+ * Herrenschmidt, IBM Corp. <benh@kernel.crashing.org>
+ *
+ * Released under the term of the GNU GPL v2.
+ *
+ *
+ *
+ * PowerMac12,1
+ * ============
+ *
+ *
+ * The algorithm used is the PID control algorithm, used the same way
+ * the published Darwin code does, using the same values that are
+ * present in the Darwin 8.10 snapshot property lists (note however
+ * that none of the code has been re-used, it's a complete
+ * re-implementation
+ *
+ * There is two models using PowerMac12,1. Model 2 is iMac G5 iSight
+ * 17" while Model 3 is iMac G5 20". They do have both the same
+ * controls with a tiny difference. The control-ids of hard-drive-fan
+ * and cpu-fan is swapped.
+ *
+ *
+ * Target Correction :
+ *
+ * controls have a target correction calculated as :
+ *
+ * new_min = ((((average_power * slope) >> 16) + offset) >> 16) + min_value
+ * new_value = max(new_value, max(new_min, 0))
+ *
+ * OD Fan control correction.
+ *
+ * # model_id: 2
+ * offset : -19563152
+ * slope : 1956315
+ *
+ * # model_id: 3
+ * offset : -15650652
+ * slope : 1565065
+ *
+ * HD Fan control correction.
+ *
+ * # model_id: 2
+ * offset : -15650652
+ * slope : 1565065
+ *
+ * # model_id: 3
+ * offset : -19563152
+ * slope : 1956315
+ *
+ * CPU Fan control correction.
+ *
+ * # model_id: 2
+ * offset : -25431900
+ * slope : 2543190
+ *
+ * # model_id: 3
+ * offset : -15650652
+ * slope : 1565065
+ *
+ *
+ * Target rubber-banding :
+ *
+ * Some controls have a target correction which depends on another
+ * control value. The correction is computed in the following way :
+ *
+ * new_min = ref_value * slope + offset
+ *
+ * ref_value is the value of the reference control. If new_min is
+ * greater than 0, then we correct the target value using :
+ *
+ * new_target = max (new_target, new_min >> 16)
+ *
+ *
+ * # model_id : 2
+ * control : cpu-fan
+ * ref : optical-drive-fan
+ * offset : -15650652
+ * slope : 1565065
+ *
+ * # model_id : 3
+ * control : optical-drive-fan
+ * ref : hard-drive-fan
+ * offset : -32768000
+ * slope : 65536
+ *
+ *
+ * In order to have the moste efficient correction with those
+ * dependencies, we must trigger HD loop before OD loop before CPU
+ * loop.
+ *
+ *
+ * The various control loops found in Darwin config file are:
+ *
+ * HD Fan control loop.
+ *
+ * # model_id: 2
+ * control : hard-drive-fan
+ * sensor : hard-drive-temp
+ * PID params : G_d = 0x00000000
+ * G_p = 0x002D70A3
+ * G_r = 0x00019999
+ * History = 2 entries
+ * Input target = 0x370000
+ * Interval = 5s
+ *
+ * # model_id: 3
+ * control : hard-drive-fan
+ * sensor : hard-drive-temp
+ * PID params : G_d = 0x00000000
+ * G_p = 0x002170A3
+ * G_r = 0x00019999
+ * History = 2 entries
+ * Input target = 0x370000
+ * Interval = 5s
+ *
+ * OD Fan control loop.
+ *
+ * # model_id: 2
+ * control : optical-drive-fan
+ * sensor : optical-drive-temp
+ * PID params : G_d = 0x00000000
+ * G_p = 0x001FAE14
+ * G_r = 0x00019999
+ * History = 2 entries
+ * Input target = 0x320000
+ * Interval = 5s
+ *
+ * # model_id: 3
+ * control : optical-drive-fan
+ * sensor : optical-drive-temp
+ * PID params : G_d = 0x00000000
+ * G_p = 0x001FAE14
+ * G_r = 0x00019999
+ * History = 2 entries
+ * Input target = 0x320000
+ * Interval = 5s
+ *
+ * GPU Fan control loop.
+ *
+ * # model_id: 2
+ * control : hard-drive-fan
+ * sensor : gpu-temp
+ * PID params : G_d = 0x00000000
+ * G_p = 0x002A6666
+ * G_r = 0x00019999
+ * History = 2 entries
+ * Input target = 0x5A0000
+ * Interval = 5s
+ *
+ * # model_id: 3
+ * control : cpu-fan
+ * sensor : gpu-temp
+ * PID params : G_d = 0x00000000
+ * G_p = 0x0010CCCC
+ * G_r = 0x00019999
+ * History = 2 entries
+ * Input target = 0x500000
+ * Interval = 5s
+ *
+ * KODIAK (aka northbridge) Fan control loop.
+ *
+ * # model_id: 2
+ * control : optical-drive-fan
+ * sensor : north-bridge-temp
+ * PID params : G_d = 0x00000000
+ * G_p = 0x003BD70A
+ * G_r = 0x00019999
+ * History = 2 entries
+ * Input target = 0x550000
+ * Interval = 5s
+ *
+ * # model_id: 3
+ * control : hard-drive-fan
+ * sensor : north-bridge-temp
+ * PID params : G_d = 0x00000000
+ * G_p = 0x0030F5C2
+ * G_r = 0x00019999
+ * History = 2 entries
+ * Input target = 0x550000
+ * Interval = 5s
+ *
+ * CPU Fan control loop.
+ *
+ * control : cpu-fan
+ * sensors : cpu-temp, cpu-power
+ * PID params : from SDB partition
+ *
+ *
+ * CPU Slew control loop.
+ *
+ * control : cpufreq-clamp
+ * sensor : cpu-temp
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/kmod.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/sections.h>
+#include <asm/smu.h>
+
+#include "windfarm.h"
+#include "windfarm_pid.h"
+
+#define VERSION "0.3"
+
+static int pm121_mach_model; /* machine model id */
+
+/* Controls & sensors */
+static struct wf_sensor *sensor_cpu_power;
+static struct wf_sensor *sensor_cpu_temp;
+static struct wf_sensor *sensor_cpu_voltage;
+static struct wf_sensor *sensor_cpu_current;
+static struct wf_sensor *sensor_gpu_temp;
+static struct wf_sensor *sensor_north_bridge_temp;
+static struct wf_sensor *sensor_hard_drive_temp;
+static struct wf_sensor *sensor_optical_drive_temp;
+static struct wf_sensor *sensor_incoming_air_temp; /* unused ! */
+
+enum {
+ FAN_CPU,
+ FAN_HD,
+ FAN_OD,
+ CPUFREQ,
+ N_CONTROLS
+};
+static struct wf_control *controls[N_CONTROLS] = {};
+
+/* Set to kick the control loop into life */
+static int pm121_all_controls_ok, pm121_all_sensors_ok, pm121_started;
+
+enum {
+ FAILURE_FAN = 1 << 0,
+ FAILURE_SENSOR = 1 << 1,
+ FAILURE_OVERTEMP = 1 << 2
+};
+
+/* All sys loops. Note the HD before the OD loop in order to have it
+ run before. */
+enum {
+ LOOP_GPU, /* control = hd or cpu, but luckily,
+ it doesn't matter */
+ LOOP_HD, /* control = hd */
+ LOOP_KODIAK, /* control = hd or od */
+ LOOP_OD, /* control = od */
+ N_LOOPS
+};
+
+static const char *loop_names[N_LOOPS] = {
+ "GPU",
+ "HD",
+ "KODIAK",
+ "OD",
+};
+
+#define PM121_NUM_CONFIGS 2
+
+static unsigned int pm121_failure_state;
+static int pm121_readjust, pm121_skipping;
+static s32 average_power;
+
+struct pm121_correction {
+ int offset;
+ int slope;
+};
+
+static struct pm121_correction corrections[N_CONTROLS][PM121_NUM_CONFIGS] = {
+ /* FAN_OD */
+ {
+ /* MODEL 2 */
+ { .offset = -19563152,
+ .slope = 1956315
+ },
+ /* MODEL 3 */
+ { .offset = -15650652,
+ .slope = 1565065
+ },
+ },
+ /* FAN_HD */
+ {
+ /* MODEL 2 */
+ { .offset = -15650652,
+ .slope = 1565065
+ },
+ /* MODEL 3 */
+ { .offset = -19563152,
+ .slope = 1956315
+ },
+ },
+ /* FAN_CPU */
+ {
+ /* MODEL 2 */
+ { .offset = -25431900,
+ .slope = 2543190
+ },
+ /* MODEL 3 */
+ { .offset = -15650652,
+ .slope = 1565065
+ },
+ },
+ /* CPUFREQ has no correction (and is not implemented at all) */
+};
+
+struct pm121_connection {
+ unsigned int control_id;
+ unsigned int ref_id;
+ struct pm121_correction correction;
+};
+
+static struct pm121_connection pm121_connections[] = {
+ /* MODEL 2 */
+ { .control_id = FAN_CPU,
+ .ref_id = FAN_OD,
+ { .offset = -32768000,
+ .slope = 65536
+ }
+ },
+ /* MODEL 3 */
+ { .control_id = FAN_OD,
+ .ref_id = FAN_HD,
+ { .offset = -32768000,
+ .slope = 65536
+ }
+ },
+};
+
+/* pointer to the current model connection */
+static struct pm121_connection *pm121_connection;
+
+/*
+ * ****** System Fans Control Loop ******
+ *
+ */
+
+/* Since each loop handles only one control and we want to avoid
+ * writing virtual control, we store the control correction with the
+ * loop params. Some data are not set, there are common to all loop
+ * and thus, hardcoded.
+ */
+struct pm121_sys_param {
+ /* purely informative since we use mach_model-2 as index */
+ int model_id;
+ struct wf_sensor **sensor; /* use sensor_id instead ? */
+ s32 gp, itarget;
+ unsigned int control_id;
+};
+
+static struct pm121_sys_param
+pm121_sys_all_params[N_LOOPS][PM121_NUM_CONFIGS] = {
+ /* GPU Fan control loop */
+ {
+ { .model_id = 2,
+ .sensor = &sensor_gpu_temp,
+ .gp = 0x002A6666,
+ .itarget = 0x5A0000,
+ .control_id = FAN_HD,
+ },
+ { .model_id = 3,
+ .sensor = &sensor_gpu_temp,
+ .gp = 0x0010CCCC,
+ .itarget = 0x500000,
+ .control_id = FAN_CPU,
+ },
+ },
+ /* HD Fan control loop */
+ {
+ { .model_id = 2,
+ .sensor = &sensor_hard_drive_temp,
+ .gp = 0x002D70A3,
+ .itarget = 0x370000,
+ .control_id = FAN_HD,
+ },
+ { .model_id = 3,
+ .sensor = &sensor_hard_drive_temp,
+ .gp = 0x002170A3,
+ .itarget = 0x370000,
+ .control_id = FAN_HD,
+ },
+ },
+ /* KODIAK Fan control loop */
+ {
+ { .model_id = 2,
+ .sensor = &sensor_north_bridge_temp,
+ .gp = 0x003BD70A,
+ .itarget = 0x550000,
+ .control_id = FAN_OD,
+ },
+ { .model_id = 3,
+ .sensor = &sensor_north_bridge_temp,
+ .gp = 0x0030F5C2,
+ .itarget = 0x550000,
+ .control_id = FAN_HD,
+ },
+ },
+ /* OD Fan control loop */
+ {
+ { .model_id = 2,
+ .sensor = &sensor_optical_drive_temp,
+ .gp = 0x001FAE14,
+ .itarget = 0x320000,
+ .control_id = FAN_OD,
+ },
+ { .model_id = 3,
+ .sensor = &sensor_optical_drive_temp,
+ .gp = 0x001FAE14,
+ .itarget = 0x320000,
+ .control_id = FAN_OD,
+ },
+ },
+};
+
+/* the hardcoded values */
+#define PM121_SYS_GD 0x00000000
+#define PM121_SYS_GR 0x00019999
+#define PM121_SYS_HISTORY_SIZE 2
+#define PM121_SYS_INTERVAL 5
+
+/* State data used by the system fans control loop
+ */
+struct pm121_sys_state {
+ int ticks;
+ s32 setpoint;
+ struct wf_pid_state pid;
+};
+
+struct pm121_sys_state *pm121_sys_state[N_LOOPS] = {};
+
+/*
+ * ****** CPU Fans Control Loop ******
+ *
+ */
+
+#define PM121_CPU_INTERVAL 1
+
+/* State data used by the cpu fans control loop
+ */
+struct pm121_cpu_state {
+ int ticks;
+ s32 setpoint;
+ struct wf_cpu_pid_state pid;
+};
+
+static struct pm121_cpu_state *pm121_cpu_state;
+
+
+
+/*
+ * ***** Implementation *****
+ *
+ */
+
+/* correction the value using the output-low-bound correction algo */
+static s32 pm121_correct(s32 new_setpoint,
+ unsigned int control_id,
+ s32 min)
+{
+ s32 new_min;
+ struct pm121_correction *correction;
+ correction = &corrections[control_id][pm121_mach_model - 2];
+
+ new_min = (average_power * correction->slope) >> 16;
+ new_min += correction->offset;
+ new_min = (new_min >> 16) + min;
+
+ return max(new_setpoint, max(new_min, 0));
+}
+
+static s32 pm121_connect(unsigned int control_id, s32 setpoint)
+{
+ s32 new_min, value, new_setpoint;
+
+ if (pm121_connection->control_id == control_id) {
+ controls[control_id]->ops->get_value(controls[control_id],
+ &value);
+ new_min = value * pm121_connection->correction.slope;
+ new_min += pm121_connection->correction.offset;
+ if (new_min > 0) {
+ new_setpoint = max(setpoint, (new_min >> 16));
+ if (new_setpoint != setpoint) {
+ pr_debug("pm121: %s depending on %s, "
+ "corrected from %d to %d RPM\n",
+ controls[control_id]->name,
+ controls[pm121_connection->ref_id]->name,
+ (int) setpoint, (int) new_setpoint);
+ }
+ } else
+ new_setpoint = setpoint;
+ }
+ /* no connection */
+ else
+ new_setpoint = setpoint;
+
+ return new_setpoint;
+}
+
+/* FAN LOOPS */
+static void pm121_create_sys_fans(int loop_id)
+{
+ struct pm121_sys_param *param = NULL;
+ struct wf_pid_param pid_param;
+ struct wf_control *control = NULL;
+ int i;
+
+ /* First, locate the params for this model */
+ for (i = 0; i < PM121_NUM_CONFIGS; i++) {
+ if (pm121_sys_all_params[loop_id][i].model_id == pm121_mach_model) {
+ param = &(pm121_sys_all_params[loop_id][i]);
+ break;
+ }
+ }
+
+ /* No params found, put fans to max */
+ if (param == NULL) {
+ printk(KERN_WARNING "pm121: %s fan config not found "
+ " for this machine model\n",
+ loop_names[loop_id]);
+ goto fail;
+ }
+
+ control = controls[param->control_id];
+
+ /* Alloc & initialize state */
+ pm121_sys_state[loop_id] = kmalloc(sizeof(struct pm121_sys_state),
+ GFP_KERNEL);
+ if (pm121_sys_state[loop_id] == NULL) {
+ printk(KERN_WARNING "pm121: Memory allocation error\n");
+ goto fail;
+ }
+ pm121_sys_state[loop_id]->ticks = 1;
+
+ /* Fill PID params */
+ pid_param.gd = PM121_SYS_GD;
+ pid_param.gp = param->gp;
+ pid_param.gr = PM121_SYS_GR;
+ pid_param.interval = PM121_SYS_INTERVAL;
+ pid_param.history_len = PM121_SYS_HISTORY_SIZE;
+ pid_param.itarget = param->itarget;
+ pid_param.min = control->ops->get_min(control);
+ pid_param.max = control->ops->get_max(control);
+
+ wf_pid_init(&pm121_sys_state[loop_id]->pid, &pid_param);
+
+ pr_debug("pm121: %s Fan control loop initialized.\n"
+ " itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
+ loop_names[loop_id], FIX32TOPRINT(pid_param.itarget),
+ pid_param.min, pid_param.max);
+ return;
+
+ fail:
+ /* note that this is not optimal since another loop may still
+ control the same control */
+ printk(KERN_WARNING "pm121: failed to set up %s loop "
+ "setting \"%s\" to max speed.\n",
+ loop_names[loop_id], control->name);
+
+ if (control)
+ wf_control_set_max(control);
+}
+
+static void pm121_sys_fans_tick(int loop_id)
+{
+ struct pm121_sys_param *param;
+ struct pm121_sys_state *st;
+ struct wf_sensor *sensor;
+ struct wf_control *control;
+ s32 temp, new_setpoint;
+ int rc;
+
+ param = &(pm121_sys_all_params[loop_id][pm121_mach_model-2]);
+ st = pm121_sys_state[loop_id];
+ sensor = *(param->sensor);
+ control = controls[param->control_id];
+
+ if (--st->ticks != 0) {
+ if (pm121_readjust)
+ goto readjust;
+ return;
+ }
+ st->ticks = PM121_SYS_INTERVAL;
+
+ rc = sensor->ops->get_value(sensor, &temp);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: %s sensor error %d\n",
+ sensor->name, rc);
+ pm121_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ pr_debug("pm121: %s Fan tick ! %s: %d.%03d\n",
+ loop_names[loop_id], sensor->name,
+ FIX32TOPRINT(temp));
+
+ new_setpoint = wf_pid_run(&st->pid, temp);
+
+ /* correction */
+ new_setpoint = pm121_correct(new_setpoint,
+ param->control_id,
+ st->pid.param.min);
+ /* linked corretion */
+ new_setpoint = pm121_connect(param->control_id, new_setpoint);
+
+ if (new_setpoint == st->setpoint)
+ return;
+ st->setpoint = new_setpoint;
+ pr_debug("pm121: %s corrected setpoint: %d RPM\n",
+ control->name, (int)new_setpoint);
+ readjust:
+ if (control && pm121_failure_state == 0) {
+ rc = control->ops->set_value(control, st->setpoint);
+ if (rc) {
+ printk(KERN_WARNING "windfarm: %s fan error %d\n",
+ control->name, rc);
+ pm121_failure_state |= FAILURE_FAN;
+ }
+ }
+}
+
+
+/* CPU LOOP */
+static void pm121_create_cpu_fans(void)
+{
+ struct wf_cpu_pid_param pid_param;
+ const struct smu_sdbp_header *hdr;
+ struct smu_sdbp_cpupiddata *piddata;
+ struct smu_sdbp_fvt *fvt;
+ struct wf_control *fan_cpu;
+ s32 tmax, tdelta, maxpow, powadj;
+
+ fan_cpu = controls[FAN_CPU];
+
+ /* First, locate the PID params in SMU SBD */
+ hdr = smu_get_sdb_partition(SMU_SDB_CPUPIDDATA_ID, NULL);
+ if (hdr == 0) {
+ printk(KERN_WARNING "pm121: CPU PID fan config not found.\n");
+ goto fail;
+ }
+ piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
+
+ /* Get the FVT params for operating point 0 (the only supported one
+ * for now) in order to get tmax
+ */
+ hdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
+ if (hdr) {
+ fvt = (struct smu_sdbp_fvt *)&hdr[1];
+ tmax = ((s32)fvt->maxtemp) << 16;
+ } else
+ tmax = 0x5e0000; /* 94 degree default */
+
+ /* Alloc & initialize state */
+ pm121_cpu_state = kmalloc(sizeof(struct pm121_cpu_state),
+ GFP_KERNEL);
+ if (pm121_cpu_state == NULL)
+ goto fail;
+ pm121_cpu_state->ticks = 1;
+
+ /* Fill PID params */
+ pid_param.interval = PM121_CPU_INTERVAL;
+ pid_param.history_len = piddata->history_len;
+ if (pid_param.history_len > WF_CPU_PID_MAX_HISTORY) {
+ printk(KERN_WARNING "pm121: History size overflow on "
+ "CPU control loop (%d)\n", piddata->history_len);
+ pid_param.history_len = WF_CPU_PID_MAX_HISTORY;
+ }
+ pid_param.gd = piddata->gd;
+ pid_param.gp = piddata->gp;
+ pid_param.gr = piddata->gr / pid_param.history_len;
+
+ tdelta = ((s32)piddata->target_temp_delta) << 16;
+ maxpow = ((s32)piddata->max_power) << 16;
+ powadj = ((s32)piddata->power_adj) << 16;
+
+ pid_param.tmax = tmax;
+ pid_param.ttarget = tmax - tdelta;
+ pid_param.pmaxadj = maxpow - powadj;
+
+ pid_param.min = fan_cpu->ops->get_min(fan_cpu);
+ pid_param.max = fan_cpu->ops->get_max(fan_cpu);
+
+ wf_cpu_pid_init(&pm121_cpu_state->pid, &pid_param);
+
+ pr_debug("pm121: CPU Fan control initialized.\n");
+ pr_debug(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM,\n",
+ FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax),
+ pid_param.min, pid_param.max);
+
+ return;
+
+ fail:
+ printk(KERN_WARNING "pm121: CPU fan config not found, max fan speed\n");
+
+ if (controls[CPUFREQ])
+ wf_control_set_max(controls[CPUFREQ]);
+ if (fan_cpu)
+ wf_control_set_max(fan_cpu);
+}
+
+
+static void pm121_cpu_fans_tick(struct pm121_cpu_state *st)
+{
+ s32 new_setpoint, temp, power;
+ struct wf_control *fan_cpu = NULL;
+ int rc;
+
+ if (--st->ticks != 0) {
+ if (pm121_readjust)
+ goto readjust;
+ return;
+ }
+ st->ticks = PM121_CPU_INTERVAL;
+
+ fan_cpu = controls[FAN_CPU];
+
+ rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
+ if (rc) {
+ printk(KERN_WARNING "pm121: CPU temp sensor error %d\n",
+ rc);
+ pm121_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
+ if (rc) {
+ printk(KERN_WARNING "pm121: CPU power sensor error %d\n",
+ rc);
+ pm121_failure_state |= FAILURE_SENSOR;
+ return;
+ }
+
+ pr_debug("pm121: CPU Fans tick ! CPU temp: %d.%03d°C, power: %d.%03d\n",
+ FIX32TOPRINT(temp), FIX32TOPRINT(power));
+
+ if (temp > st->pid.param.tmax)
+ pm121_failure_state |= FAILURE_OVERTEMP;
+
+ new_setpoint = wf_cpu_pid_run(&st->pid, power, temp);
+
+ /* correction */
+ new_setpoint = pm121_correct(new_setpoint,
+ FAN_CPU,
+ st->pid.param.min);
+
+ /* connected correction */
+ new_setpoint = pm121_connect(FAN_CPU, new_setpoint);
+
+ if (st->setpoint == new_setpoint)
+ return;
+ st->setpoint = new_setpoint;
+ pr_debug("pm121: CPU corrected setpoint: %d RPM\n", (int)new_setpoint);
+
+ readjust:
+ if (fan_cpu && pm121_failure_state == 0) {
+ rc = fan_cpu->ops->set_value(fan_cpu, st->setpoint);
+ if (rc) {
+ printk(KERN_WARNING "pm121: %s fan error %d\n",
+ fan_cpu->name, rc);
+ pm121_failure_state |= FAILURE_FAN;
+ }
+ }
+}
+
+/*
+ * ****** Common ******
+ *
+ */
+
+static void pm121_tick(void)
+{
+ unsigned int last_failure = pm121_failure_state;
+ unsigned int new_failure;
+ s32 total_power;
+ int i;
+
+ if (!pm121_started) {
+ pr_debug("pm121: creating control loops !\n");
+ for (i = 0; i < N_LOOPS; i++)
+ pm121_create_sys_fans(i);
+
+ pm121_create_cpu_fans();
+ pm121_started = 1;
+ }
+
+ /* skipping ticks */
+ if (pm121_skipping && --pm121_skipping)
+ return;
+
+ /* compute average power */
+ total_power = 0;
+ for (i = 0; i < pm121_cpu_state->pid.param.history_len; i++)
+ total_power += pm121_cpu_state->pid.powers[i];
+
+ average_power = total_power / pm121_cpu_state->pid.param.history_len;
+
+
+ pm121_failure_state = 0;
+ for (i = 0 ; i < N_LOOPS; i++) {
+ if (pm121_sys_state[i])
+ pm121_sys_fans_tick(i);
+ }
+
+ if (pm121_cpu_state)
+ pm121_cpu_fans_tick(pm121_cpu_state);
+
+ pm121_readjust = 0;
+ new_failure = pm121_failure_state & ~last_failure;
+
+ /* If entering failure mode, clamp cpufreq and ramp all
+ * fans to full speed.
+ */
+ if (pm121_failure_state && !last_failure) {
+ for (i = 0; i < N_CONTROLS; i++) {
+ if (controls[i])
+ wf_control_set_max(controls[i]);
+ }
+ }
+
+ /* If leaving failure mode, unclamp cpufreq and readjust
+ * all fans on next iteration
+ */
+ if (!pm121_failure_state && last_failure) {
+ if (controls[CPUFREQ])
+ wf_control_set_min(controls[CPUFREQ]);
+ pm121_readjust = 1;
+ }
+
+ /* Overtemp condition detected, notify and start skipping a couple
+ * ticks to let the temperature go down
+ */
+ if (new_failure & FAILURE_OVERTEMP) {
+ wf_set_overtemp();
+ pm121_skipping = 2;
+ }
+
+ /* We only clear the overtemp condition if overtemp is cleared
+ * _and_ no other failure is present. Since a sensor error will
+ * clear the overtemp condition (can't measure temperature) at
+ * the control loop levels, but we don't want to keep it clear
+ * here in this case
+ */
+ if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
+ wf_clear_overtemp();
+}
+
+
+static struct wf_control* pm121_register_control(struct wf_control *ct,
+ const char *match,
+ unsigned int id)
+{
+ if (controls[id] == NULL && !strcmp(ct->name, match)) {
+ if (wf_get_control(ct) == 0)
+ controls[id] = ct;
+ }
+ return controls[id];
+}
+
+static void pm121_new_control(struct wf_control *ct)
+{
+ int all = 1;
+
+ if (pm121_all_controls_ok)
+ return;
+
+ all = pm121_register_control(ct, "optical-drive-fan", FAN_OD) && all;
+ all = pm121_register_control(ct, "hard-drive-fan", FAN_HD) && all;
+ all = pm121_register_control(ct, "cpu-fan", FAN_CPU) && all;
+ all = pm121_register_control(ct, "cpufreq-clamp", CPUFREQ) && all;
+
+ if (all)
+ pm121_all_controls_ok = 1;
+}
+
+
+
+
+static struct wf_sensor* pm121_register_sensor(struct wf_sensor *sensor,
+ const char *match,
+ struct wf_sensor **var)
+{
+ if (*var == NULL && !strcmp(sensor->name, match)) {
+ if (wf_get_sensor(sensor) == 0)
+ *var = sensor;
+ }
+ return *var;
+}
+
+static void pm121_new_sensor(struct wf_sensor *sr)
+{
+ int all = 1;
+
+ if (pm121_all_sensors_ok)
+ return;
+
+ all = pm121_register_sensor(sr, "cpu-temp",
+ &sensor_cpu_temp) && all;
+ all = pm121_register_sensor(sr, "cpu-current",
+ &sensor_cpu_current) && all;
+ all = pm121_register_sensor(sr, "cpu-voltage",
+ &sensor_cpu_voltage) && all;
+ all = pm121_register_sensor(sr, "cpu-power",
+ &sensor_cpu_power) && all;
+ all = pm121_register_sensor(sr, "hard-drive-temp",
+ &sensor_hard_drive_temp) && all;
+ all = pm121_register_sensor(sr, "optical-drive-temp",
+ &sensor_optical_drive_temp) && all;
+ all = pm121_register_sensor(sr, "incoming-air-temp",
+ &sensor_incoming_air_temp) && all;
+ all = pm121_register_sensor(sr, "north-bridge-temp",
+ &sensor_north_bridge_temp) && all;
+ all = pm121_register_sensor(sr, "gpu-temp",
+ &sensor_gpu_temp) && all;
+
+ if (all)
+ pm121_all_sensors_ok = 1;
+}
+
+
+
+static int pm121_notify(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ switch (event) {
+ case WF_EVENT_NEW_CONTROL:
+ pr_debug("pm121: new control %s detected\n",
+ ((struct wf_control *)data)->name);
+ pm121_new_control(data);
+ break;
+ case WF_EVENT_NEW_SENSOR:
+ pr_debug("pm121: new sensor %s detected\n",
+ ((struct wf_sensor *)data)->name);
+ pm121_new_sensor(data);
+ break;
+ case WF_EVENT_TICK:
+ if (pm121_all_controls_ok && pm121_all_sensors_ok)
+ pm121_tick();
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block pm121_events = {
+ .notifier_call = pm121_notify,
+};
+
+static int pm121_init_pm(void)
+{
+ const struct smu_sdbp_header *hdr;
+
+ hdr = smu_get_sdb_partition(SMU_SDB_SENSORTREE_ID, NULL);
+ if (hdr != 0) {
+ struct smu_sdbp_sensortree *st =
+ (struct smu_sdbp_sensortree *)&hdr[1];
+ pm121_mach_model = st->model_id;
+ }
+
+ pm121_connection = &pm121_connections[pm121_mach_model - 2];
+
+ printk(KERN_INFO "pm121: Initializing for iMac G5 iSight model ID %d\n",
+ pm121_mach_model);
+
+ return 0;
+}
+
+
+static int pm121_probe(struct platform_device *ddev)
+{
+ wf_register_client(&pm121_events);
+
+ return 0;
+}
+
+static int __devexit pm121_remove(struct platform_device *ddev)
+{
+ wf_unregister_client(&pm121_events);
+ return 0;
+}
+
+static struct platform_driver pm121_driver = {
+ .probe = pm121_probe,
+ .remove = __devexit_p(pm121_remove),
+ .driver = {
+ .name = "windfarm",
+ .bus = &platform_bus_type,
+ },
+};
+
+
+static int __init pm121_init(void)
+{
+ int rc = -ENODEV;
+
+ if (machine_is_compatible("PowerMac12,1"))
+ rc = pm121_init_pm();
+
+ if (rc == 0) {
+ request_module("windfarm_smu_controls");
+ request_module("windfarm_smu_sensors");
+ request_module("windfarm_smu_sat");
+ request_module("windfarm_lm75_sensor");
+ request_module("windfarm_max6690_sensor");
+ request_module("windfarm_cpufreq_clamp");
+ platform_driver_register(&pm121_driver);
+ }
+
+ return rc;
+}
+
+static void __exit pm121_exit(void)
+{
+
+ platform_driver_unregister(&pm121_driver);
+}
+
+
+module_init(pm121_init);
+module_exit(pm121_exit);
+
+MODULE_AUTHOR("Étienne Bersac <bersace@gmail.com>");
+MODULE_DESCRIPTION("Thermal control logic for iMac G5 (iSight)");
+MODULE_LICENSE("GPL");
+
Index: linux-work/drivers/macintosh/windfarm_smu_controls.c
===================================================================
--- linux-work.orig/drivers/macintosh/windfarm_smu_controls.c 2007-09-28 11:42:07.000000000 +1000
+++ linux-work/drivers/macintosh/windfarm_smu_controls.c 2008-04-29 15:32:50.000000000 +1000
@@ -218,6 +218,10 @@ static struct smu_fan_control *smu_fan_c
fct->ctrl.name = "cpu-fan";
else if (!strcmp(l, "Hard Drive") || !strcmp(l, "Hard drive"))
fct->ctrl.name = "drive-bay-fan";
+ else if (!strcmp(l, "HDD Fan")) /* seen on iMac G5 iSight */
+ fct->ctrl.name = "hard-drive-fan";
+ else if (!strcmp(l, "ODD Fan")) /* same */
+ fct->ctrl.name = "optical-drive-fan";
/* Unrecognized fan, bail out */
if (fct->ctrl.name == NULL)
^ permalink raw reply
* Re: [RESEND][PATCH 1/2][POWERPC] PIKA Warp: Update platform code tosupportRev B boards
From: Sean MacLennan @ 2008-04-29 5:42 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Stephen Rothwell
In-Reply-To: <18454.44365.719572.654726@cargo.ozlabs.ibm.com>
On Tue, 29 Apr 2008 15:08:29 +1000
"Paul Mackerras" <paulus@samba.org> wrote:
> It doesn't help that both of these patches have the same subject line,
> nor that it starts with "Re:". :(
Sorry about that. I just split up the two patches, but the same subject
does apply to both. The code currently in the mainline kernel is for a
Rev A. Since there are no Rev As outside of PIKA, that is not very
useful. These patches bring the platform code up to Rev B standards
(while still maintaining Rev A support).
So the subject is correct for both.
> Also, I find the statement "A change to the dts to get gpios correct
> broke the led code" a bit opaque. It doesn't tell me in what way it
> was broken or what this patch does to correct, or even what the change
> was in enough detail that I could find the change in the git
> repository.
You won't find it. One of the problems is that I am basically adding
patches to patches to patches, but since none of them are in a
mainline git, they all just keep showing up as one big patch.
That comment was meant as a quick note to explain why the platform patch
changed from the previous platform patch. Short of diffing the
patches, you can't easily see how they changed.
After the Warp is released (sometime in May), the hardware churn should
end and I can submit patches one at a time rather than one massive
patch.
Cheers,
Sean
^ permalink raw reply
* [PATCH] devres: support addresses greater than an unsigned long via dev_ioremap
From: Kumar Gala @ 2008-04-29 6:22 UTC (permalink / raw)
To: htejun, Andrew Morton, jgarzik; +Cc: linuxppc-dev, linux-kernel
Use a resource_size_t instead of unsigned long since some arch's are
capable of having ioremap deal with addresses greater than the size of a
unsigned long.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
include/linux/io.h | 4 ++--
lib/devres.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/linux/io.h b/include/linux/io.h
index e3b2dda..831f57c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -58,9 +58,9 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)
}
#endif
-void __iomem * devm_ioremap(struct device *dev, unsigned long offset,
+void __iomem * devm_ioremap(struct device *dev, resource_size_t offset,
unsigned long size);
-void __iomem * devm_ioremap_nocache(struct device *dev, unsigned long offset,
+void __iomem * devm_ioremap_nocache(struct device *dev, resource_size_t offset,
unsigned long size);
void devm_iounmap(struct device *dev, void __iomem *addr);
int check_signature(const volatile void __iomem *io_addr,
diff --git a/lib/devres.c b/lib/devres.c
index edc27a5..26c87c4 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -20,7 +20,7 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
*
* Managed ioremap(). Map is automatically unmapped on driver detach.
*/
-void __iomem *devm_ioremap(struct device *dev, unsigned long offset,
+void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
unsigned long size)
{
void __iomem **ptr, *addr;
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(devm_ioremap);
* Managed ioremap_nocache(). Map is automatically unmapped on driver
* detach.
*/
-void __iomem *devm_ioremap_nocache(struct device *dev, unsigned long offset,
+void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
unsigned long size)
{
void __iomem **ptr, *addr;
--
1.5.4.1
^ permalink raw reply related
* build failure on efika
From: Paul Mackerras @ 2008-04-29 6:27 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
My test builds for efika currently fail with this message:
FATAL: drivers/serial/mpc52xx_uart: struct of_device_id is not terminated with a NULL entry!
make[2]: *** [__modpost] Error 1
make[1]: *** [modules] Error 2
make: *** [sub-make] Error 2
Could you do a little patch to add the NULL entry please?
Paul.
^ permalink raw reply
* Re: [PATCH] devres: support addresses greater than an unsigned long via dev_ioremap
From: Tejun Heo @ 2008-04-29 6:30 UTC (permalink / raw)
To: Kumar Gala; +Cc: Andrew Morton, linuxppc-dev, jgarzik, linux-kernel
In-Reply-To: <Pine.LNX.4.64.0804290122210.10928@blarg.am.freescale.net>
Kumar Gala wrote:
> Use a resource_size_t instead of unsigned long since some arch's are
> capable of having ioremap deal with addresses greater than the size of a
> unsigned long.
>
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Acked-by: Tejun Heo <htejun@gmail.com>
Thanks.
--
tejun
^ permalink raw reply
* Re: [PATCH] devres: support addresses greater than an unsigned long via dev_ioremap
From: Jeff Garzik @ 2008-04-29 6:37 UTC (permalink / raw)
To: Tejun Heo
Cc: Andrew Morton, Greg KH, Jesse Barnes, linux-kernel, linuxppc-dev
In-Reply-To: <4816C094.6030601@gmail.com>
Tejun Heo wrote:
> Kumar Gala wrote:
>> Use a resource_size_t instead of unsigned long since some arch's are
>> capable of having ioremap deal with addresses greater than the size of a
>> unsigned long.
>>
>> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
>
> Acked-by: Tejun Heo <htejun@gmail.com>
Fine with me, too.
I think devres changes should go via GregKH (device core) or Jesse (PCI)
rather than my libata tree, unless there are obvious dependencies...
Jeff
^ permalink raw reply
* (no subject)
From: Chen Gong @ 2008-04-29 8:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: wim, linux-kernel
this patch only makes a few fixes for latest kernel git tree
^ permalink raw reply
* [PATCH] Watchdog on MPC85xx SMP system
From: Chen Gong @ 2008-04-29 8:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: wim, Chen Gong, linux-kernel
In-Reply-To: <1209458525-8041-1-git-send-email-g.chen@freescale.com>
On Book-E SMP systems each core has its own private watchdog.
If only one watchdog is enabled, when the core that doesn't
enable the watchdog is hung, system can't reset because no
watchdog is running on it. That's bad. It means we must
enable watchdogs on both cores.
We can use smp_call_function() to send appropriate messages to
all the other cores to enable and update the watchdog.
Signed-off-by: Chen Gong <g.chen@freescale.com>
---
Now Tested on MPC8572DS platform.
drivers/watchdog/booke_wdt.c | 31 +++++++++++++++++++++++--------
1 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index d362f5b..8a4e7f0 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -1,12 +1,12 @@
/*
- * drivers/char/watchdog/booke_wdt.c
+ * drivers/watchdog/booke_wdt.c
*
* Watchdog timer for PowerPC Book-E systems
*
* Author: Matthew McClintock
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
*
- * Copyright 2005 Freescale Semiconductor Inc.
+ * Copyright 2005, 2008 Freescale Semiconductor Inc.
*
* 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
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/smp.h>
#include <linux/miscdevice.h>
#include <linux/notifier.h>
#include <linux/watchdog.h>
@@ -47,23 +48,31 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
#define WDTP(x) (TCR_WP(x))
#endif
+static DEFINE_SPINLOCK(booke_wdt_lock);
+
+static void __booke_wdt_ping(void *data)
+{
+ mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
+}
+
/*
* booke_wdt_ping:
*/
static __inline__ void booke_wdt_ping(void)
{
- mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
+ smp_call_function(__booke_wdt_ping, NULL, 0, 0);
+ __booke_wdt_ping(NULL);
}
/*
- * booke_wdt_enable:
+ * __booke_wdt_enable:
*/
-static __inline__ void booke_wdt_enable(void)
+static inline void __booke_wdt_enable(void *data)
{
u32 val;
/* clear status before enabling watchdog */
- booke_wdt_ping();
+ __booke_wdt_ping(NULL);
val = mfspr(SPRN_TCR);
val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));
@@ -137,12 +146,15 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file,
*/
static int booke_wdt_open (struct inode *inode, struct file *file)
{
+ spin_lock(&booke_wdt_lock);
if (booke_wdt_enabled == 0) {
booke_wdt_enabled = 1;
- booke_wdt_enable();
+ __booke_wdt_enable(NULL);
+ smp_call_function(__booke_wdt_enable, NULL, 0, 0);
printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
booke_wdt_period);
}
+ spin_unlock(&booke_wdt_lock);
return nonseekable_open(inode, file);
}
@@ -183,11 +195,14 @@ static int __init booke_wdt_init(void)
return ret;
}
+ spin_lock(&booke_wdt_lock);
if (booke_wdt_enabled == 1) {
printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
booke_wdt_period);
- booke_wdt_enable();
+ __booke_wdt_enable(NULL);
+ smp_call_function(__booke_wdt_enable, NULL, 0, 0);
}
+ spin_unlock(&booke_wdt_lock);
return ret;
}
--
1.5.4
^ permalink raw reply related
* Re: Virtex4FX12LC hangs in calibrating delay loop
From: wangyanlong @ 2008-04-29 8:53 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20070621151554.GA22663@cip.informatik.uni-erlangen.de>
I meet the same problem as yours , have you fix your problem now ??? I am
keep trying !!!!
Thomas Glanzmann wrote:
>
> Hello,
> I used the HEAD secretlabs kernel and used ml403 defconfig. I still see
> no serial output from the _kernel_ on the serial console. But I do see
> output from the in kernel embedded boot loader "load_kernel". I typed in
> stop in xmd and got an instruction pointer which points to:
>
> c00045a0 <__delay>:
> c00045a0: 2c 03 00 00 cmpwi r3,0
> c00045a4: 7c 69 03 a6 mtctr r3
> c00045a8: 4d 82 00 20 beqlr
> c00045ac: 42 00 00 00 bdnz- c00045ac <__delay+0xc>
> <<<<<<<<
> c00045b0: 4e 80 00 20 blr
>
> So I guess it is the calibrating delay loop and I am not sure. I can
> reproduce
> this. It is always in this function. Now I wonder is my board missing
> timer interrupts? What could be the reason for this. And of course one
> much more important question:
>
> - Is the serial console initialized before or after the
> calibrating delay loop?
>
> Is there a way to get a backtrace out of this? If that is the case what
> do I have to do? Recompile the Kernel with frame pointers and attach
> gdb?
>
> Thomas
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
--
View this message in context: http://www.nabble.com/Virtex4FX12LC-hangs-in-calibrating-delay-loop-tp11235297p16955743.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* overloading existing PTRACE_GET_DEBUGREG/PTRACE_SET_DEBUGREG commands
From: Kumar Gala @ 2008-04-29 8:56 UTC (permalink / raw)
To: Paul Mackerras
Cc: linuxppc-dev@ozlabs.org list, Anton Blanchard, Roland McGrath,
Paralkar Anmol
It looks like when Anton added the PTRACE_GET_DEBUGREG/
PTRACE_SET_DEBUGREG he envisioned future chips having more than one
IABR/DABR.
I'm wondering what the feeling is about using the commands for
handling some of the sub-arch variants we have:
e300 (603 style machine) - adds IABR2, DABR2, IBCR (control) and DBCR
(control). We can use IABR1/2 (and DABR1/2) either as unique
addresses or for various ranges (inclusive or exclusive)
Book-e class machines can have the following registers: DBCR[0-2],
IAC1-4, DAC1-2, DVC1-2, DBSR. IACs are roughly equivalent to IABRs,
DACs are roughly equivalent to DABRs. Booke has similar ability to
the e300 to do inclusive, exclusive ranges as well as some other
features.
My question is how to handle providing access to the debug resources
we have on these other machine types. Should we just use GET_DEBUGREG/
SET_DEBUGREG and specify what the buffers look like for these specific
machine types? Is it ok to overload the commands this way? How does
this play with utrace?
Also, what functionality can GDB take advantage of today? Does it
comprehend the idea of breakpoints or watchpoints that cover a range?
- k
^ permalink raw reply
* Re: HAVE_CONFIG
From: Arnd Bergmann @ 2008-04-29 9:27 UTC (permalink / raw)
To: linuxppc-embedded, dhlii
In-Reply-To: <4816B372.10608@dlasys.net>
On Tuesday 29 April 2008, David H. Lynch Jr. wrote:
> =A0 =A0 Why does CONFIG_PPC set CONFIG_HAVE_IDE ?
Because it's possible to build ide drivers on the powerpc architecture.
It means you get the option to enable to disable the old ATA (IDE) drivers.
Arnd <><
^ permalink raw reply
* Re: [PATCH 2/2] Raise the upper limit of NR_CPUS and move the pacas into the BSS.
From: Arnd Bergmann @ 2008-04-29 9:46 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <6bbf4d3637c9b72f9f0a4cf8a6f2c322c0784d7e.1209008469.git.tony@bakeyournoodle.com>
On Thursday 24 April 2008, Tony Breeds wrote:
> This patch adds the required functionality to fill in all pacas at runtim=
e.
>=20
> With NR_CPUS=3D1024
> text =A0 =A0data =A0 =A0 bss =A0 =A0 dec =A0 =A0 hex filename
> =A0137 1704032 =A0 =A0 =A0 0 1704169 =A01a00e9 arch/powerpc/kernel/paca.o=
:Before
> =A0121 1179744 =A0524288 1704153 =A01a00d9 arch/powerpc/kernel/paca.o :Af=
ter
>=20
> Also remove unneeded #includes from arch/powerpc/kernel/paca.c
>=20
> Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
Maybe we can go even further than this: Since it is now a substantial amount
of .bss, maybe the unused parts can be returned to the buddy allocator
using free_bootmem or similar once you know how many CPUs there are?
I know that this would be an evil hack, but it may still be worth it.
Your patch should certainly go in first though, freeing the memory would
be an additional extension.
Arnd <><
^ permalink raw reply
* Re: HAVE_CONFIG
From: David H. Lynch Jr. @ 2008-04-29 9:56 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-embedded
In-Reply-To: <200804291127.14666.arnd@arndb.de>
Arnd Bergmann wrote:
> On Tuesday 29 April 2008, David H. Lynch Jr. wrote:
>
>> Why does CONFIG_PPC set CONFIG_HAVE_IDE ?
>>
>
> Because it's possible to build ide drivers on the powerpc architecture.
> It means you get the option to enable to disable the old ATA (IDE) drivers.
>
> Arnd <><
>
So CONFIG_HAVE_IDE means the architecture could have IDE rather than
it does have IDE ?
My BSP can't have IDE, does that mean I should add
default n if MYBSP
? or somehow deselect HAVE_IDE in the config option for my BSP ?
--
Dave Lynch DLA Systems
Software Development: Embedded Linux
717.627.3770 dhlii@dlasys.net http://www.dlasys.net
fax: 1.253.369.9244 Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too numerous to list.
"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction."
Albert Einstein
^ permalink raw reply
* Re: HAVE_CONFIG
From: Arnd Bergmann @ 2008-04-29 10:03 UTC (permalink / raw)
To: dhlii; +Cc: linuxppc-embedded
In-Reply-To: <4816F0CF.2080800@dlasys.net>
On Tuesday 29 April 2008, David H. Lynch Jr. wrote:
> Arnd Bergmann wrote:
> > On Tuesday 29 April 2008, David H. Lynch Jr. wrote:
> > =A0=20
> >> =A0 =A0 Why does CONFIG_PPC set CONFIG_HAVE_IDE ?
> >> =A0 =A0=20
> >
> > Because it's possible to build ide drivers on the powerpc architecture.
> > It means you get the option to enable to disable the old ATA (IDE) driv=
ers.
> >
> > =A0=A0=A0=A0=A0=A0Arnd <><
> > =A0=20
> =A0 =A0 So CONFIG_HAVE_IDE means the architecture could have IDE rather t=
han
> it does have IDE ?
Right.
> =A0 =A0 My BSP can't have IDE, does that mean I should add
> =A0 =A0
> =A0 =A0 default n if MYBSP
>=20
> =A0 =A0 ? or somehow deselect HAVE_IDE in the config option for my BSP ?
No.
You can always build multiplatform kernels, and your BSP Kconfig should do
nothing to forbid this. The only time where you don't want to set HAVE_IDE
is when it is impossible to build the IDE drivers. However, if your code
does not allow building support for IDE into the kernel, you should fix your
code rather than disable the Kconfig.
Arnd <><
^ permalink raw reply
* [PATCH 0/2 v2] i2c: Add support for device alias names
From: Jean Delvare @ 2008-04-29 10:42 UTC (permalink / raw)
To: Linux I2C
Cc: Laurent, Sievers, linuxppc-dev list, Paul Mundt, Scott Wood, Kay
Hi all,
This is yesterday's patch set updated to apply cleanly (and hopefully
work) on top of 2.6.25-git13. Basically the only change since yesterday
is the sync with the rtc subsystem updates, which converted 3 drivers
(rtc-x1205, rtc-pcf8563 and rtc-isl1208).
The plan is to send this to Linus this evening. The more testing it
gets, the better. Thanks to Wolfram and Jochen for yesterday's test
reports!
--
Jean Delvare
^ permalink raw reply
* [PATCH 1/2 v2] i2c: Add support for device alias names
From: Jean Delvare @ 2008-04-29 10:46 UTC (permalink / raw)
To: Linux I2C
Cc: Laurent, Sievers, linuxppc-dev list, Paul Mundt, Scott Wood, Kay
In-Reply-To: <20080429124241.08e18ae3@hyperion.delvare>
Based on earlier work by Jon Smirl and Jochen Friedrich.
This patch allows new-style i2c chip drivers to have alias names using
the official kernel aliasing system and MODULE_DEVICE_TABLE(). At this
point, the old i2c driver binding scheme (driver_name/type) is still
supported.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Jochen Friedrich <jochen@scram.de>
Cc: Jon Smirl <jonsmirl@gmail.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
---
Documentation/i2c/writing-clients | 3 +
drivers/gpio/pca953x.c | 3 +
drivers/gpio/pcf857x.c | 3 +
drivers/hwmon/f75375s.c | 8 ++--
drivers/i2c/chips/ds1682.c | 3 +
drivers/i2c/chips/menelaus.c | 3 +
drivers/i2c/chips/tps65010.c | 3 +
drivers/i2c/chips/tsl2550.c | 3 +
drivers/i2c/i2c-core.c | 51 +++++++++++++++++++++++-----
drivers/media/video/cs5345.c | 3 +
drivers/media/video/cs53l32a.c | 3 +
drivers/media/video/cx25840/cx25840-core.c | 3 +
drivers/media/video/m52790.c | 3 +
drivers/media/video/msp3400-driver.c | 2 -
drivers/media/video/mt9m001.c | 3 +
drivers/media/video/mt9v022.c | 3 +
drivers/media/video/saa7115.c | 3 +
drivers/media/video/saa7127.c | 3 +
drivers/media/video/saa717x.c | 3 +
drivers/media/video/tcm825x.c | 3 +
drivers/media/video/tlv320aic23b.c | 3 +
drivers/media/video/tuner-core.c | 3 +
drivers/media/video/tvaudio.c | 2 -
drivers/media/video/upd64031a.c | 3 +
drivers/media/video/upd64083.c | 3 +
drivers/media/video/v4l2-common.c | 5 +-
drivers/media/video/vp27smpx.c | 3 +
drivers/media/video/wm8739.c | 3 +
drivers/media/video/wm8775.c | 3 +
drivers/rtc/rtc-ds1307.c | 3 +
drivers/rtc/rtc-ds1374.c | 3 +
drivers/rtc/rtc-isl1208.c | 2 -
drivers/rtc/rtc-m41t80.c | 3 +
drivers/rtc/rtc-pcf8563.c | 3 +
drivers/rtc/rtc-rs5c372.c | 3 +
drivers/rtc/rtc-s35390a.c | 3 +
drivers/rtc/rtc-x1205.c | 3 +
include/linux/i2c.h | 5 +-
include/linux/mod_devicetable.h | 11 ++++++
include/media/v4l2-common.h | 4 +-
include/media/v4l2-i2c-drv-legacy.h | 2 -
include/media/v4l2-i2c-drv.h | 2 -
scripts/mod/file2alias.c | 13 +++++++
43 files changed, 146 insertions(+), 54 deletions(-)
--- linux-2.6.26-rc0.orig/Documentation/i2c/writing-clients 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/Documentation/i2c/writing-clients 2008-04-29 08:37:43.000000000 +0200
@@ -164,7 +164,8 @@ I2C device drivers using this binding mo
kind of driver in Linux: they provide a probe() method to bind to
those devices, and a remove() method to unbind.
- static int foo_probe(struct i2c_client *client);
+ static int foo_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
static int foo_remove(struct i2c_client *client);
Remember that the i2c_driver does not create those client handles. The
--- linux-2.6.26-rc0.orig/drivers/gpio/pca953x.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/gpio/pca953x.c 2008-04-29 08:37:43.000000000 +0200
@@ -192,7 +192,8 @@ static void pca953x_setup_gpio(struct pc
gc->owner = THIS_MODULE;
}
-static int __devinit pca953x_probe(struct i2c_client *client)
+static int __devinit pca953x_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
--- linux-2.6.26-rc0.orig/drivers/gpio/pcf857x.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/gpio/pcf857x.c 2008-04-29 08:37:43.000000000 +0200
@@ -142,7 +142,8 @@ static void pcf857x_set16(struct gpio_ch
/*-------------------------------------------------------------------------*/
-static int pcf857x_probe(struct i2c_client *client)
+static int pcf857x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct pcf857x_platform_data *pdata;
struct pcf857x *gpio;
--- linux-2.6.26-rc0.orig/drivers/hwmon/f75375s.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/hwmon/f75375s.c 2008-04-29 08:37:43.000000000 +0200
@@ -117,7 +117,8 @@ struct f75375_data {
static int f75375_attach_adapter(struct i2c_adapter *adapter);
static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
static int f75375_detach_client(struct i2c_client *client);
-static int f75375_probe(struct i2c_client *client);
+static int f75375_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
static int f75375_remove(struct i2c_client *client);
static struct i2c_driver f75375_legacy_driver = {
@@ -628,7 +629,8 @@ static void f75375_init(struct i2c_clien
}
-static int f75375_probe(struct i2c_client *client)
+static int f75375_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct f75375_data *data = i2c_get_clientdata(client);
struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
@@ -748,7 +750,7 @@ static int f75375_detect(struct i2c_adap
if ((err = i2c_attach_client(client)))
goto exit_free;
- if ((err = f75375_probe(client)) < 0)
+ if ((err = f75375_probe(client, NULL)) < 0)
goto exit_detach;
return 0;
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/ds1682.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/ds1682.c 2008-04-29 08:37:43.000000000 +0200
@@ -200,7 +200,8 @@ static struct bin_attribute ds1682_eepro
/*
* Called when a ds1682 device is matched with this driver
*/
-static int ds1682_probe(struct i2c_client *client)
+static int ds1682_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int rc;
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/menelaus.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/menelaus.c 2008-04-29 08:37:43.000000000 +0200
@@ -1149,7 +1149,8 @@ static inline void menelaus_rtc_init(str
static struct i2c_driver menelaus_i2c_driver;
-static int menelaus_probe(struct i2c_client *client)
+static int menelaus_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct menelaus_chip *menelaus;
int rev = 0, val;
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/tps65010.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/tps65010.c 2008-04-29 08:37:43.000000000 +0200
@@ -532,7 +532,8 @@ static int __exit tps65010_remove(struct
return 0;
}
-static int tps65010_probe(struct i2c_client *client)
+static int tps65010_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct tps65010 *tps;
int status;
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/tsl2550.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/tsl2550.c 2008-04-29 08:37:43.000000000 +0200
@@ -364,7 +364,8 @@ static int tsl2550_init_client(struct i2
*/
static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client)
+static int __devinit tsl2550_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct tsl2550_data *data;
--- linux-2.6.26-rc0.orig/drivers/i2c/i2c-core.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/i2c-core.c 2008-04-29 08:37:43.000000000 +0200
@@ -48,6 +48,17 @@ static DEFINE_IDR(i2c_adapter_idr);
/* ------------------------------------------------------------------------- */
+static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
+ const struct i2c_client *client)
+{
+ while (id->name[0]) {
+ if (strcmp(client->name, id->name) == 0)
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -59,6 +70,10 @@ static int i2c_device_match(struct devic
if (!is_newstyle_driver(driver))
return 0;
+ /* match on an id table if there is one */
+ if (driver->id_table)
+ return i2c_match_id(driver->id_table, client) != NULL;
+
/* new style drivers use the same kind of driver matching policy
* as platform devices or SPI: compare device and driver IDs.
*/
@@ -73,11 +88,17 @@ static int i2c_device_uevent(struct devi
struct i2c_client *client = to_i2c_client(dev);
/* by definition, legacy drivers can't hotplug */
- if (dev->driver || !client->driver_name)
+ if (dev->driver)
return 0;
- if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
- return -ENOMEM;
+ if (client->driver_name[0]) {
+ if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
+ return -ENOMEM;
+ } else {
+ if (add_uevent_var(env, "MODALIAS=%s%s",
+ I2C_MODULE_PREFIX, client->name))
+ return -ENOMEM;
+ }
dev_dbg(dev, "uevent\n");
return 0;
}
@@ -90,13 +111,19 @@ static int i2c_device_probe(struct devic
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
+ const struct i2c_device_id *id;
int status;
if (!driver->probe)
return -ENODEV;
client->driver = driver;
dev_dbg(dev, "probe\n");
- status = driver->probe(client);
+
+ if (driver->id_table)
+ id = i2c_match_id(driver->id_table, client);
+ else
+ id = NULL;
+ status = driver->probe(client, id);
if (status)
client->driver = NULL;
return status;
@@ -179,9 +206,9 @@ static ssize_t show_client_name(struct d
static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
- return client->driver_name
+ return client->driver_name[0]
? sprintf(buf, "%s\n", client->driver_name)
- : 0;
+ : sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
}
static struct device_attribute i2c_dev_attrs[] = {
@@ -300,15 +327,21 @@ void i2c_unregister_device(struct i2c_cl
EXPORT_SYMBOL_GPL(i2c_unregister_device);
-static int dummy_nop(struct i2c_client *client)
+static int dummy_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return 0;
+}
+
+static int dummy_remove(struct i2c_client *client)
{
return 0;
}
static struct i2c_driver dummy_driver = {
.driver.name = "dummy",
- .probe = dummy_nop,
- .remove = dummy_nop,
+ .probe = dummy_probe,
+ .remove = dummy_remove,
};
/**
--- linux-2.6.26-rc0.orig/drivers/media/video/cs5345.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/cs5345.c 2008-04-29 08:37:43.000000000 +0200
@@ -142,7 +142,8 @@ static int cs5345_command(struct i2c_cli
/* ----------------------------------------------------------------------- */
-static int cs5345_probe(struct i2c_client *client)
+static int cs5345_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
--- linux-2.6.26-rc0.orig/drivers/media/video/cs53l32a.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/cs53l32a.c 2008-04-29 08:37:43.000000000 +0200
@@ -135,7 +135,8 @@ static int cs53l32a_command(struct i2c_c
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static int cs53l32a_probe(struct i2c_client *client)
+static int cs53l32a_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i;
--- linux-2.6.26-rc0.orig/drivers/media/video/cx25840/cx25840-core.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/cx25840/cx25840-core.c 2008-04-29 08:37:43.000000000 +0200
@@ -1209,7 +1209,8 @@ static int cx25840_command(struct i2c_cl
/* ----------------------------------------------------------------------- */
-static int cx25840_probe(struct i2c_client *client)
+static int cx25840_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct cx25840_state *state;
u32 id;
--- linux-2.6.26-rc0.orig/drivers/media/video/m52790.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/m52790.c 2008-04-29 08:37:43.000000000 +0200
@@ -126,7 +126,8 @@ static int m52790_command(struct i2c_cli
/* i2c implementation */
-static int m52790_probe(struct i2c_client *client)
+static int m52790_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct m52790_state *state;
--- linux-2.6.26-rc0.orig/drivers/media/video/msp3400-driver.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/msp3400-driver.c 2008-04-29 08:37:43.000000000 +0200
@@ -805,7 +805,7 @@ static int msp_resume(struct i2c_client
/* ----------------------------------------------------------------------- */
-static int msp_probe(struct i2c_client *client)
+static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct msp_state *state;
int (*thread_func)(void *data) = NULL;
--- linux-2.6.26-rc0.orig/drivers/media/video/mt9m001.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/mt9m001.c 2008-04-29 08:37:43.000000000 +0200
@@ -620,7 +620,8 @@ static void mt9m001_video_remove(struct
soc_camera_video_stop(&mt9m001->icd);
}
-static int mt9m001_probe(struct i2c_client *client)
+static int mt9m001_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct mt9m001 *mt9m001;
struct soc_camera_device *icd;
--- linux-2.6.26-rc0.orig/drivers/media/video/mt9v022.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/mt9v022.c 2008-04-29 08:37:43.000000000 +0200
@@ -745,7 +745,8 @@ static void mt9v022_video_remove(struct
soc_camera_video_stop(&mt9v022->icd);
}
-static int mt9v022_probe(struct i2c_client *client)
+static int mt9v022_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct mt9v022 *mt9v022;
struct soc_camera_device *icd;
--- linux-2.6.26-rc0.orig/drivers/media/video/saa7115.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/saa7115.c 2008-04-29 08:37:43.000000000 +0200
@@ -1450,7 +1450,8 @@ static int saa7115_command(struct i2c_cl
/* ----------------------------------------------------------------------- */
-static int saa7115_probe(struct i2c_client *client)
+static int saa7115_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct saa711x_state *state;
int i;
--- linux-2.6.26-rc0.orig/drivers/media/video/saa7127.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/saa7127.c 2008-04-29 08:37:43.000000000 +0200
@@ -661,7 +661,8 @@ static int saa7127_command(struct i2c_cl
/* ----------------------------------------------------------------------- */
-static int saa7127_probe(struct i2c_client *client)
+static int saa7127_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct saa7127_state *state;
struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
--- linux-2.6.26-rc0.orig/drivers/media/video/saa717x.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/saa717x.c 2008-04-29 08:37:43.000000000 +0200
@@ -1418,7 +1418,8 @@ static int saa717x_command(struct i2c_cl
/* i2c implementation */
/* ----------------------------------------------------------------------- */
-static int saa717x_probe(struct i2c_client *client)
+static int saa717x_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct saa717x_state *decoder;
u8 id = 0;
--- linux-2.6.26-rc0.orig/drivers/media/video/tcm825x.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/tcm825x.c 2008-04-29 08:37:43.000000000 +0200
@@ -840,7 +840,8 @@ static struct v4l2_int_device tcm825x_in
},
};
-static int tcm825x_probe(struct i2c_client *client)
+static int tcm825x_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
{
struct tcm825x_sensor *sensor = &tcm825x;
int rval;
--- linux-2.6.26-rc0.orig/drivers/media/video/tlv320aic23b.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/tlv320aic23b.c 2008-04-29 08:37:43.000000000 +0200
@@ -125,7 +125,8 @@ static int tlv320aic23b_command(struct i
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static int tlv320aic23b_probe(struct i2c_client *client)
+static int tlv320aic23b_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct tlv320aic23b_state *state;
--- linux-2.6.26-rc0.orig/drivers/media/video/tuner-core.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/tuner-core.c 2008-04-29 08:37:43.000000000 +0200
@@ -1073,7 +1073,8 @@ static void tuner_lookup(struct i2c_adap
/* During client attach, set_type is called by adapter's attach_inform callback.
set_type must then be completed by tuner_probe.
*/
-static int tuner_probe(struct i2c_client *client)
+static int tuner_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct tuner *t;
struct tuner *radio;
--- linux-2.6.26-rc0.orig/drivers/media/video/tvaudio.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/tvaudio.c 2008-04-29 08:37:43.000000000 +0200
@@ -1461,7 +1461,7 @@ static struct CHIPDESC chiplist[] = {
/* ---------------------------------------------------------------------- */
/* i2c registration */
-static int chip_probe(struct i2c_client *client)
+static int chip_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct CHIPSTATE *chip;
struct CHIPDESC *desc;
--- linux-2.6.26-rc0.orig/drivers/media/video/upd64031a.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/upd64031a.c 2008-04-29 08:37:43.000000000 +0200
@@ -195,7 +195,8 @@ static int upd64031a_command(struct i2c_
/* i2c implementation */
-static int upd64031a_probe(struct i2c_client *client)
+static int upd64031a_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct upd64031a_state *state;
int i;
--- linux-2.6.26-rc0.orig/drivers/media/video/upd64083.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/upd64083.c 2008-04-29 08:37:43.000000000 +0200
@@ -172,7 +172,8 @@ static int upd64083_command(struct i2c_c
/* i2c implementation */
-static int upd64083_probe(struct i2c_client *client)
+static int upd64083_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct upd64083_state *state;
int i;
--- linux-2.6.26-rc0.orig/drivers/media/video/v4l2-common.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/v4l2-common.c 2008-04-29 08:37:43.000000000 +0200
@@ -710,7 +710,8 @@ EXPORT_SYMBOL(v4l2_chip_ident_i2c_client
/* Helper function for I2C legacy drivers */
int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
- const char *name, int (*probe)(struct i2c_client *))
+ const char *name,
+ int (*probe)(struct i2c_client *, const struct i2c_device_id *))
{
struct i2c_client *client;
int err;
@@ -724,7 +725,7 @@ int v4l2_i2c_attach(struct i2c_adapter *
client->driver = driver;
strlcpy(client->name, name, sizeof(client->name));
- err = probe(client);
+ err = probe(client, NULL);
if (err == 0) {
i2c_attach_client(client);
} else {
--- linux-2.6.26-rc0.orig/drivers/media/video/vp27smpx.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/vp27smpx.c 2008-04-29 08:37:43.000000000 +0200
@@ -121,7 +121,8 @@ static int vp27smpx_command(struct i2c_c
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static int vp27smpx_probe(struct i2c_client *client)
+static int vp27smpx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct vp27smpx_state *state;
--- linux-2.6.26-rc0.orig/drivers/media/video/wm8739.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/wm8739.c 2008-04-29 08:37:43.000000000 +0200
@@ -261,7 +261,8 @@ static int wm8739_command(struct i2c_cli
/* i2c implementation */
-static int wm8739_probe(struct i2c_client *client)
+static int wm8739_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct wm8739_state *state;
--- linux-2.6.26-rc0.orig/drivers/media/video/wm8775.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/wm8775.c 2008-04-29 08:37:43.000000000 +0200
@@ -159,7 +159,8 @@ static int wm8775_command(struct i2c_cli
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static int wm8775_probe(struct i2c_client *client)
+static int wm8775_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct wm8775_state *state;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-ds1307.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-ds1307.c 2008-04-29 08:37:43.000000000 +0200
@@ -326,7 +326,8 @@ static struct bin_attribute nvram = {
static struct i2c_driver ds1307_driver;
-static int __devinit ds1307_probe(struct i2c_client *client)
+static int __devinit ds1307_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct ds1307 *ds1307;
int err = -ENODEV;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-ds1374.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-ds1374.c 2008-04-29 08:37:43.000000000 +0200
@@ -355,7 +355,8 @@ static const struct rtc_class_ops ds1374
.ioctl = ds1374_ioctl,
};
-static int ds1374_probe(struct i2c_client *client)
+static int ds1374_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct ds1374 *ds1374;
int ret;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-isl1208.c 2008-04-29 07:41:16.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-isl1208.c 2008-04-29 08:50:01.000000000 +0200
@@ -490,7 +490,7 @@ isl1208_sysfs_unregister(struct device *
}
static int
-isl1208_probe(struct i2c_client *client)
+isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int rc = 0;
struct rtc_device *rtc;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-m41t80.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-m41t80.c 2008-04-29 08:37:43.000000000 +0200
@@ -756,7 +756,8 @@ static struct notifier_block wdt_notifie
*
*****************************************************************************
*/
-static int m41t80_probe(struct i2c_client *client)
+static int m41t80_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i, rc = 0;
struct rtc_device *rtc = NULL;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-pcf8563.c 2008-04-29 07:41:16.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-pcf8563.c 2008-04-29 08:49:41.000000000 +0200
@@ -246,7 +246,8 @@ static const struct rtc_class_ops pcf856
.set_time = pcf8563_rtc_set_time,
};
-static int pcf8563_probe(struct i2c_client *client)
+static int pcf8563_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct pcf8563 *pcf8563;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-rs5c372.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-rs5c372.c 2008-04-29 08:37:43.000000000 +0200
@@ -494,7 +494,8 @@ static void rs5c_sysfs_unregister(struct
static struct i2c_driver rs5c372_driver;
-static int rs5c372_probe(struct i2c_client *client)
+static int rs5c372_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int err = 0;
struct rs5c372 *rs5c372;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-s35390a.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-s35390a.c 2008-04-29 08:37:43.000000000 +0200
@@ -195,7 +195,8 @@ static const struct rtc_class_ops s35390
static struct i2c_driver s35390a_driver;
-static int s35390a_probe(struct i2c_client *client)
+static int s35390a_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int err;
unsigned int i;
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-x1205.c 2008-04-29 07:41:16.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-x1205.c 2008-04-29 08:48:52.000000000 +0200
@@ -494,7 +494,8 @@ static void x1205_sysfs_unregister(struc
}
-static int x1205_probe(struct i2c_client *client)
+static int x1205_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int err = 0;
unsigned char sr;
--- linux-2.6.26-rc0.orig/include/linux/i2c.h 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/include/linux/i2c.h 2008-04-29 08:37:43.000000000 +0200
@@ -126,7 +126,7 @@ struct i2c_driver {
* With the driver model, device enumeration is NEVER done by drivers;
* it's done by infrastructure. (NEW STYLE DRIVERS ONLY)
*/
- int (*probe)(struct i2c_client *);
+ int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);
/* driver model interfaces that don't relate to enumeration */
@@ -140,11 +140,10 @@ struct i2c_driver {
int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
struct device_driver driver;
+ const struct i2c_device_id *id_table;
};
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
-#define I2C_NAME_SIZE 20
-
/**
* struct i2c_client - represent an I2C slave device
* @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
--- linux-2.6.26-rc0.orig/include/linux/mod_devicetable.h 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/include/linux/mod_devicetable.h 2008-04-29 08:37:43.000000000 +0200
@@ -368,4 +368,15 @@ struct virtio_device_id {
};
#define VIRTIO_DEV_ANY_ID 0xffffffff
+/* i2c */
+
+#define I2C_NAME_SIZE 20
+#define I2C_MODULE_PREFIX "i2c:"
+
+struct i2c_device_id {
+ char name[I2C_NAME_SIZE];
+ kernel_ulong_t driver_data; /* Data private to the driver */
+};
+
+
#endif /* LINUX_MOD_DEVICETABLE_H */
--- linux-2.6.26-rc0.orig/include/media/v4l2-common.h 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/include/media/v4l2-common.h 2008-04-29 08:37:43.000000000 +0200
@@ -107,9 +107,11 @@ int v4l2_chip_match_host(u32 id_type, u3
struct i2c_driver;
struct i2c_adapter;
struct i2c_client;
+struct i2c_device_id;
int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
- const char *name, int (*probe)(struct i2c_client *));
+ const char *name,
+ int (*probe)(struct i2c_client *, const struct i2c_device_id *));
/* ------------------------------------------------------------------------- */
--- linux-2.6.26-rc0.orig/include/media/v4l2-i2c-drv-legacy.h 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/include/media/v4l2-i2c-drv-legacy.h 2008-04-29 08:37:43.000000000 +0200
@@ -25,7 +25,7 @@ struct v4l2_i2c_driver_data {
const char * const name;
int driverid;
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
- int (*probe)(struct i2c_client *client);
+ int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
int (*remove)(struct i2c_client *client);
int (*suspend)(struct i2c_client *client, pm_message_t state);
int (*resume)(struct i2c_client *client);
--- linux-2.6.26-rc0.orig/include/media/v4l2-i2c-drv.h 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/include/media/v4l2-i2c-drv.h 2008-04-29 08:37:43.000000000 +0200
@@ -30,7 +30,7 @@ struct v4l2_i2c_driver_data {
const char * const name;
int driverid;
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
- int (*probe)(struct i2c_client *client);
+ int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
int (*remove)(struct i2c_client *client);
int (*suspend)(struct i2c_client *client, pm_message_t state);
int (*resume)(struct i2c_client *client);
--- linux-2.6.26-rc0.orig/scripts/mod/file2alias.c 2008-04-29 08:13:00.000000000 +0200
+++ linux-2.6.26-rc0/scripts/mod/file2alias.c 2008-04-29 08:37:43.000000000 +0200
@@ -576,6 +576,15 @@ static int do_virtio_entry(const char *f
return 1;
}
+/* Looks like: i2c:S */
+static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
+ char *alias)
+{
+ sprintf(alias, I2C_MODULE_PREFIX "%s", id->name);
+
+ return 1;
+}
+
/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
@@ -704,6 +713,10 @@ void handle_moddevtable(struct module *m
do_table(symval, sym->st_size,
sizeof(struct virtio_device_id), "virtio",
do_virtio_entry, mod);
+ else if (sym_is(symname, "__mod_i2c_device_table"))
+ do_table(symval, sym->st_size,
+ sizeof(struct i2c_device_id), "i2c",
+ do_i2c_entry, mod);
free(zeros);
}
--
Jean Delvare
^ permalink raw reply
* [PATCH 2/2 v2] i2c: Convert most new-style drivers to use module aliasing
From: Jean Delvare @ 2008-04-29 10:47 UTC (permalink / raw)
To: Linux I2C
Cc: Laurent, Sievers, linuxppc-dev list, Paul Mundt, Scott Wood, Kay
In-Reply-To: <20080429124241.08e18ae3@hyperion.delvare>
Based on earlier work by Jon Smirl and Jochen Friedrich.
Update most new-style i2c drivers to use standard module aliasing
instead of the old driver_name/type driver matching scheme. I've
left the video drivers apart (except for SoC camera drivers) as
they're a bit more diffcult to deal with, they'll have their own
patch later.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Jon Smirl <jonsmirl@gmail.com>
Cc: Jochen Friedrich <jochen@scram.de>
---
arch/arm/mach-at91/board-csb337.c | 3 -
arch/arm/mach-at91/board-dk.c | 3 -
arch/arm/mach-at91/board-eb9200.c | 3 -
arch/arm/mach-iop32x/em7210.c | 3 -
arch/arm/mach-iop32x/glantank.c | 4 -
arch/arm/mach-iop32x/n2100.c | 4 -
arch/arm/mach-ixp4xx/dsmg600-setup.c | 2
arch/arm/mach-ixp4xx/nas100d-setup.c | 2
arch/arm/mach-ixp4xx/nslu2-setup.c | 2
arch/arm/mach-omap1/board-h2.c | 2
arch/arm/mach-omap1/board-h3.c | 3 -
arch/arm/mach-omap1/board-osk.c | 1
arch/arm/mach-orion5x/db88f5281-setup.c | 4 -
arch/arm/mach-orion5x/dns323-setup.c | 7 --
arch/arm/mach-orion5x/kurobox_pro-setup.c | 4 -
arch/arm/mach-orion5x/rd88f5182-setup.c | 4 -
arch/arm/mach-orion5x/ts209-setup.c | 3 -
arch/arm/mach-pxa/pcm990-baseboard.c | 5 -
arch/blackfin/mach-bf533/boards/stamp.c | 3 -
arch/blackfin/mach-bf537/boards/stamp.c | 3 -
arch/blackfin/mach-bf548/boards/ezkit.c | 2
arch/powerpc/sysdev/fsl_soc.c | 27 ++++------
arch/sh/boards/renesas/migor/setup.c | 3 -
arch/sh/boards/renesas/r7780rp/setup.c | 3 -
drivers/gpio/pca953x.c | 23 +-------
drivers/gpio/pcf857x.c | 33 +++++++-----
drivers/hwmon/f75375s.c | 23 ++++----
drivers/i2c/busses/i2c-taos-evm.c | 3 -
drivers/i2c/chips/ds1682.c | 7 ++
drivers/i2c/chips/menelaus.c | 7 ++
drivers/i2c/chips/tps65010.c | 29 ++++------
drivers/i2c/chips/tsl2550.c | 7 ++
drivers/media/video/mt9m001.c | 7 ++
drivers/media/video/mt9v022.c | 7 ++
drivers/rtc/rtc-ds1307.c | 63 +++++++++--------------
drivers/rtc/rtc-ds1374.c | 7 ++
drivers/rtc/rtc-isl1208.c | 7 ++
drivers/rtc/rtc-m41t80.c | 78 +++++++----------------------
drivers/rtc/rtc-pcf8563.c | 7 ++
drivers/rtc/rtc-rs5c372.c | 24 ++++----
drivers/rtc/rtc-s35390a.c | 7 ++
drivers/rtc/rtc-x1205.c | 7 ++
include/linux/i2c.h | 12 ++--
43 files changed, 211 insertions(+), 247 deletions(-)
--- linux-2.6.26-rc0.orig/arch/arm/mach-at91/board-csb337.c 2008-04-29 07:40:33.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-at91/board-csb337.c 2008-04-29 08:55:08.000000000 +0200
@@ -79,8 +79,7 @@ static struct at91_udc_data __initdata c
static struct i2c_board_info __initdata csb337_i2c_devices[] = {
{
- I2C_BOARD_INFO("rtc-ds1307", 0x68),
- .type = "ds1307",
+ I2C_BOARD_INFO("ds1307", 0x68),
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-at91/board-dk.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-at91/board-dk.c 2008-04-29 08:55:08.000000000 +0200
@@ -132,8 +132,7 @@ static struct i2c_board_info __initdata
I2C_BOARD_INFO("x9429", 0x28),
},
{
- I2C_BOARD_INFO("at24c", 0x50),
- .type = "24c1024",
+ I2C_BOARD_INFO("24c1024", 0x50),
}
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-at91/board-eb9200.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-at91/board-eb9200.c 2008-04-29 08:55:08.000000000 +0200
@@ -93,8 +93,7 @@ static struct at91_mmc_data __initdata e
static struct i2c_board_info __initdata eb9200_i2c_devices[] = {
{
- I2C_BOARD_INFO("at24c", 0x50),
- .type = "24c512",
+ I2C_BOARD_INFO("24c512", 0x50),
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-iop32x/em7210.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-iop32x/em7210.c 2008-04-29 08:55:08.000000000 +0200
@@ -50,8 +50,7 @@ static struct sys_timer em7210_timer = {
*/
static struct i2c_board_info __initdata em7210_i2c_devices[] = {
{
- I2C_BOARD_INFO("rtc-rs5c372", 0x32),
- .type = "rs5c372a",
+ I2C_BOARD_INFO("rs5c372a", 0x32),
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-iop32x/glantank.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-iop32x/glantank.c 2008-04-29 08:55:08.000000000 +0200
@@ -176,12 +176,10 @@ static struct f75375s_platform_data glan
static struct i2c_board_info __initdata glantank_i2c_devices[] = {
{
- I2C_BOARD_INFO("rtc-rs5c372", 0x32),
- .type = "rs5c372a",
+ I2C_BOARD_INFO("rs5c372a", 0x32),
},
{
I2C_BOARD_INFO("f75375", 0x2e),
- .type = "f75375",
.platform_data = &glantank_f75375s,
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-iop32x/n2100.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-iop32x/n2100.c 2008-04-29 08:55:08.000000000 +0200
@@ -208,12 +208,10 @@ static struct f75375s_platform_data n210
static struct i2c_board_info __initdata n2100_i2c_devices[] = {
{
- I2C_BOARD_INFO("rtc-rs5c372", 0x32),
- .type = "rs5c372b",
+ I2C_BOARD_INFO("rs5c372b", 0x32),
},
{
I2C_BOARD_INFO("f75375", 0x2e),
- .type = "f75375",
.platform_data = &n2100_f75375s,
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-ixp4xx/dsmg600-setup.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-ixp4xx/dsmg600-setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -65,7 +65,7 @@ static struct platform_device dsmg600_i2
static struct i2c_board_info __initdata dsmg600_i2c_board_info [] = {
{
- I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+ I2C_BOARD_INFO("pcf8563", 0x51),
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-ixp4xx/nas100d-setup.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-ixp4xx/nas100d-setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -54,7 +54,7 @@ static struct platform_device nas100d_fl
static struct i2c_board_info __initdata nas100d_i2c_board_info [] = {
{
- I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+ I2C_BOARD_INFO("pcf8563", 0x51),
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-ixp4xx/nslu2-setup.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-ixp4xx/nslu2-setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -57,7 +57,7 @@ static struct i2c_gpio_platform_data nsl
static struct i2c_board_info __initdata nslu2_i2c_board_info [] = {
{
- I2C_BOARD_INFO("rtc-x1205", 0x6f),
+ I2C_BOARD_INFO("x1205", 0x6f),
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-omap1/board-h2.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-omap1/board-h2.c 2008-04-29 08:55:08.000000000 +0200
@@ -351,11 +351,9 @@ static void __init h2_init_smc91x(void)
static struct i2c_board_info __initdata h2_i2c_board_info[] = {
{
I2C_BOARD_INFO("tps65010", 0x48),
- .type = "tps65010",
.irq = OMAP_GPIO_IRQ(58),
}, {
I2C_BOARD_INFO("isp1301_omap", 0x2d),
- .type = "isp1301_omap",
.irq = OMAP_GPIO_IRQ(2),
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-omap1/board-h3.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-omap1/board-h3.c 2008-04-29 08:55:08.000000000 +0200
@@ -473,8 +473,7 @@ static struct omap_board_config_kernel h
static struct i2c_board_info __initdata h3_i2c_board_info[] = {
{
- I2C_BOARD_INFO("tps65010", 0x48),
- .type = "tps65013",
+ I2C_BOARD_INFO("tps65013", 0x48),
/* .irq = OMAP_GPIO_IRQ(??), */
},
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-omap1/board-osk.c 2008-04-29 07:40:33.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-omap1/board-osk.c 2008-04-29 08:55:08.000000000 +0200
@@ -254,7 +254,6 @@ static struct tps65010_board tps_board =
static struct i2c_board_info __initdata osk_i2c_board_info[] = {
{
I2C_BOARD_INFO("tps65010", 0x48),
- .type = "tps65010",
.irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)),
.platform_data = &tps_board,
--- linux-2.6.26-rc0.orig/arch/arm/mach-orion5x/db88f5281-setup.c 2008-04-29 07:40:33.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-orion5x/db88f5281-setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -292,9 +292,7 @@ static struct mv643xx_eth_platform_data
* RTC DS1339 on I2C bus
****************************************************************************/
static struct i2c_board_info __initdata db88f5281_i2c_rtc = {
- .driver_name = "rtc-ds1307",
- .type = "ds1339",
- .addr = 0x68,
+ I2C_BOARD_INFO("ds1339", 0x68),
};
/*****************************************************************************
--- linux-2.6.26-rc0.orig/arch/arm/mach-orion5x/dns323-setup.c 2008-04-29 07:40:33.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-orion5x/dns323-setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -220,19 +220,16 @@ static struct platform_device *dns323_pl
static struct i2c_board_info __initdata dns323_i2c_devices[] = {
{
I2C_BOARD_INFO("g760a", 0x3e),
- .type = "g760a",
},
#if 0
/* this entry requires the new-style driver model lm75 driver,
* for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */
{
- I2C_BOARD_INFO("lm75", 0x48),
- .type = "g751",
+ I2C_BOARD_INFO("g751", 0x48),
},
#endif
{
- I2C_BOARD_INFO("rtc-m41t80", 0x68),
- .type = "m41t80",
+ I2C_BOARD_INFO("m41t80", 0x68),
}
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-orion5x/kurobox_pro-setup.c 2008-04-29 07:40:33.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-orion5x/kurobox_pro-setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -162,9 +162,7 @@ static struct mv643xx_eth_platform_data
* RTC 5C372a on I2C bus
****************************************************************************/
static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {
- .driver_name = "rtc-rs5c372",
- .type = "rs5c372a",
- .addr = 0x32,
+ I2C_BOARD_INFO("rs5c372a", 0x32),
};
/*****************************************************************************
--- linux-2.6.26-rc0.orig/arch/arm/mach-orion5x/rd88f5182-setup.c 2008-04-29 07:40:33.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-orion5x/rd88f5182-setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -224,9 +224,7 @@ static struct mv643xx_eth_platform_data
* RTC DS1338 on I2C bus
****************************************************************************/
static struct i2c_board_info __initdata rd88f5182_i2c_rtc = {
- .driver_name = "rtc-ds1307",
- .type = "ds1338",
- .addr = 0x68,
+ I2C_BOARD_INFO("ds1338", 0x68),
};
/*****************************************************************************
--- linux-2.6.26-rc0.orig/arch/arm/mach-orion5x/ts209-setup.c 2008-04-29 07:40:33.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-orion5x/ts209-setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -276,8 +276,7 @@ static void __init ts209_find_mac_addr(v
#define TS209_RTC_GPIO 3
static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
- .driver_name = "rtc-s35390a",
- .addr = 0x30,
+ I2C_BOARD_INFO("s35390a", 0x30),
.irq = 0,
};
--- linux-2.6.26-rc0.orig/arch/arm/mach-pxa/pcm990-baseboard.c 2008-04-29 07:40:33.000000000 +0200
+++ linux-2.6.26-rc0/arch/arm/mach-pxa/pcm990-baseboard.c 2008-04-29 08:55:08.000000000 +0200
@@ -320,16 +320,13 @@ static struct soc_camera_link iclink[] =
static struct i2c_board_info __initdata pcm990_i2c_devices[] = {
{
/* Must initialize before the camera(s) */
- I2C_BOARD_INFO("pca953x", 0x41),
- .type = "pca9536",
+ I2C_BOARD_INFO("pca9536", 0x41),
.platform_data = &pca9536_data,
}, {
I2C_BOARD_INFO("mt9v022", 0x48),
- .type = "mt9v022",
.platform_data = &iclink[0], /* With extender */
}, {
I2C_BOARD_INFO("mt9m001", 0x5d),
- .type = "mt9m001",
.platform_data = &iclink[0], /* With extender */
},
};
--- linux-2.6.26-rc0.orig/arch/blackfin/mach-bf533/boards/stamp.c 2008-04-29 07:40:34.000000000 +0200
+++ linux-2.6.26-rc0/arch/blackfin/mach-bf533/boards/stamp.c 2008-04-29 08:55:08.000000000 +0200
@@ -499,20 +499,17 @@ static struct i2c_board_info __initdata
#if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
{
I2C_BOARD_INFO("ad7142_joystick", 0x2C),
- .type = "ad7142_joystick",
.irq = 39,
},
#endif
#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
{
I2C_BOARD_INFO("pcf8574_lcd", 0x22),
- .type = "pcf8574_lcd",
},
#endif
#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
{
I2C_BOARD_INFO("pcf8574_keypad", 0x27),
- .type = "pcf8574_keypad",
.irq = 39,
},
#endif
--- linux-2.6.26-rc0.orig/arch/blackfin/mach-bf537/boards/stamp.c 2008-04-29 07:40:34.000000000 +0200
+++ linux-2.6.26-rc0/arch/blackfin/mach-bf537/boards/stamp.c 2008-04-29 08:55:08.000000000 +0200
@@ -751,20 +751,17 @@ static struct i2c_board_info __initdata
#if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
{
I2C_BOARD_INFO("ad7142_joystick", 0x2C),
- .type = "ad7142_joystick",
.irq = 55,
},
#endif
#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
{
I2C_BOARD_INFO("pcf8574_lcd", 0x22),
- .type = "pcf8574_lcd",
},
#endif
#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
{
I2C_BOARD_INFO("pcf8574_keypad", 0x27),
- .type = "pcf8574_keypad",
.irq = 72,
},
#endif
--- linux-2.6.26-rc0.orig/arch/blackfin/mach-bf548/boards/ezkit.c 2008-04-29 07:40:34.000000000 +0200
+++ linux-2.6.26-rc0/arch/blackfin/mach-bf548/boards/ezkit.c 2008-04-29 08:55:08.000000000 +0200
@@ -641,13 +641,11 @@ static struct i2c_board_info __initdata
#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
{
I2C_BOARD_INFO("pcf8574_lcd", 0x22),
- .type = "pcf8574_lcd",
},
#endif
#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
{
I2C_BOARD_INFO("pcf8574_keypad", 0x27),
- .type = "pcf8574_keypad",
.irq = 212,
},
#endif
--- linux-2.6.26-rc0.orig/arch/powerpc/sysdev/fsl_soc.c 2008-04-29 07:40:39.000000000 +0200
+++ linux-2.6.26-rc0/arch/powerpc/sysdev/fsl_soc.c 2008-04-29 08:55:08.000000000 +0200
@@ -418,22 +418,21 @@ arch_initcall(gfar_of_init);
#include <linux/i2c.h>
struct i2c_driver_device {
char *of_device;
- char *i2c_driver;
char *i2c_type;
};
static struct i2c_driver_device i2c_devices[] __initdata = {
- {"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
- {"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
- {"ricoh,rv5c386", "rtc-rs5c372", "rv5c386",},
- {"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
- {"dallas,ds1307", "rtc-ds1307", "ds1307",},
- {"dallas,ds1337", "rtc-ds1307", "ds1337",},
- {"dallas,ds1338", "rtc-ds1307", "ds1338",},
- {"dallas,ds1339", "rtc-ds1307", "ds1339",},
- {"dallas,ds1340", "rtc-ds1307", "ds1340",},
- {"stm,m41t00", "rtc-ds1307", "m41t00"},
- {"dallas,ds1374", "rtc-ds1374", "rtc-ds1374",},
+ {"ricoh,rs5c372a", "rs5c372a"},
+ {"ricoh,rs5c372b", "rs5c372b"},
+ {"ricoh,rv5c386", "rv5c386"},
+ {"ricoh,rv5c387a", "rv5c387a"},
+ {"dallas,ds1307", "ds1307"},
+ {"dallas,ds1337", "ds1337"},
+ {"dallas,ds1338", "ds1338"},
+ {"dallas,ds1339", "ds1339"},
+ {"dallas,ds1340", "ds1340"},
+ {"stm,m41t00", "m41t00"},
+ {"dallas,ds1374", "rtc-ds1374"},
};
static int __init of_find_i2c_driver(struct device_node *node,
@@ -444,9 +443,7 @@ static int __init of_find_i2c_driver(str
for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
if (!of_device_is_compatible(node, i2c_devices[i].of_device))
continue;
- if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
- KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
- strlcpy(info->type, i2c_devices[i].i2c_type,
+ if (strlcpy(info->type, i2c_devices[i].i2c_type,
I2C_NAME_SIZE) >= I2C_NAME_SIZE)
return -ENOMEM;
return 0;
--- linux-2.6.26-rc0.orig/arch/sh/boards/renesas/migor/setup.c 2008-04-29 07:40:40.000000000 +0200
+++ linux-2.6.26-rc0/arch/sh/boards/renesas/migor/setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -199,8 +199,7 @@ static struct platform_device *migor_dev
static struct i2c_board_info __initdata migor_i2c_devices[] = {
{
- I2C_BOARD_INFO("rtc-rs5c372", 0x32),
- .type = "rs5c372b",
+ I2C_BOARD_INFO("rs5c372b", 0x32),
},
{
I2C_BOARD_INFO("migor_ts", 0x51),
--- linux-2.6.26-rc0.orig/arch/sh/boards/renesas/r7780rp/setup.c 2008-04-29 07:40:41.000000000 +0200
+++ linux-2.6.26-rc0/arch/sh/boards/renesas/r7780rp/setup.c 2008-04-29 08:55:08.000000000 +0200
@@ -199,8 +199,7 @@ static struct platform_device smbus_devi
static struct i2c_board_info __initdata highlander_i2c_devices[] = {
{
- I2C_BOARD_INFO("rtc-rs5c372", 0x32),
- .type = "r2025sd",
+ I2C_BOARD_INFO("r2025sd", 0x32),
},
};
--- linux-2.6.26-rc0.orig/drivers/gpio/pca953x.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/gpio/pca953x.c 2008-04-29 08:55:08.000000000 +0200
@@ -23,13 +23,7 @@
#define PCA953X_INVERT 2
#define PCA953X_DIRECTION 3
-/* This is temporary - in 2.6.26 i2c_driver_data should replace it. */
-struct pca953x_desc {
- char name[I2C_NAME_SIZE];
- unsigned long driver_data;
-};
-
-static const struct pca953x_desc pca953x_descs[] = {
+static const struct i2c_device_id pca953x_id[] = {
{ "pca9534", 8, },
{ "pca9535", 16, },
{ "pca9536", 4, },
@@ -37,7 +31,9 @@ static const struct pca953x_desc pca953x
{ "pca9538", 8, },
{ "pca9539", 16, },
/* REVISIT several pca955x parts should work here too */
+ { }
};
+MODULE_DEVICE_TABLE(i2c, pca953x_id);
struct pca953x_chip {
unsigned gpio_start;
@@ -193,26 +189,16 @@ static void pca953x_setup_gpio(struct pc
}
static int __devinit pca953x_probe(struct i2c_client *client,
- const struct i2c_device_id *did)
+ const struct i2c_device_id *id)
{
struct pca953x_platform_data *pdata;
struct pca953x_chip *chip;
int ret, i;
- const struct pca953x_desc *id = NULL;
pdata = client->dev.platform_data;
if (pdata == NULL)
return -ENODEV;
- /* this loop vanishes when we get i2c_device_id */
- for (i = 0; i < ARRAY_SIZE(pca953x_descs); i++)
- if (!strcmp(pca953x_descs[i].name, client->name)) {
- id = pca953x_descs + i;
- break;
- }
- if (!id)
- return -ENODEV;
-
chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
@@ -292,6 +278,7 @@ static struct i2c_driver pca953x_driver
},
.probe = pca953x_probe,
.remove = pca953x_remove,
+ .id_table = pca953x_id,
};
static int __init pca953x_init(void)
--- linux-2.6.26-rc0.orig/drivers/gpio/pcf857x.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/gpio/pcf857x.c 2008-04-29 08:55:08.000000000 +0200
@@ -26,6 +26,21 @@
#include <asm/gpio.h>
+static const struct i2c_device_id pcf857x_id[] = {
+ { "pcf8574", 8 },
+ { "pca8574", 8 },
+ { "pca9670", 8 },
+ { "pca9672", 8 },
+ { "pca9674", 8 },
+ { "pcf8575", 16 },
+ { "pca8575", 16 },
+ { "pca9671", 16 },
+ { "pca9673", 16 },
+ { "pca9675", 16 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, pcf857x_id);
+
/*
* The pcf857x, pca857x, and pca967x chips only expose one read and one
* write register. Writing a "one" bit (to match the reset state) lets
@@ -173,13 +188,8 @@ static int pcf857x_probe(struct i2c_clie
*
* NOTE: we don't distinguish here between *4 and *4a parts.
*/
- if (strcmp(client->name, "pcf8574") == 0
- || strcmp(client->name, "pca8574") == 0
- || strcmp(client->name, "pca9670") == 0
- || strcmp(client->name, "pca9672") == 0
- || strcmp(client->name, "pca9674") == 0
- ) {
- gpio->chip.ngpio = 8;
+ gpio->chip.ngpio = id->driver_data;
+ if (gpio->chip.ngpio == 8) {
gpio->chip.direction_input = pcf857x_input8;
gpio->chip.get = pcf857x_get8;
gpio->chip.direction_output = pcf857x_output8;
@@ -199,13 +209,7 @@ static int pcf857x_probe(struct i2c_clie
*
* NOTE: we don't distinguish here between '75 and '75c parts.
*/
- } else if (strcmp(client->name, "pcf8575") == 0
- || strcmp(client->name, "pca8575") == 0
- || strcmp(client->name, "pca9671") == 0
- || strcmp(client->name, "pca9673") == 0
- || strcmp(client->name, "pca9675") == 0
- ) {
- gpio->chip.ngpio = 16;
+ } else if (gpio->chip.ngpio == 16) {
gpio->chip.direction_input = pcf857x_input16;
gpio->chip.get = pcf857x_get16;
gpio->chip.direction_output = pcf857x_output16;
@@ -314,6 +318,7 @@ static struct i2c_driver pcf857x_driver
},
.probe = pcf857x_probe,
.remove = pcf857x_remove,
+ .id_table = pcf857x_id,
};
static int __init pcf857x_init(void)
--- linux-2.6.26-rc0.orig/drivers/hwmon/f75375s.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/hwmon/f75375s.c 2008-04-29 08:55:08.000000000 +0200
@@ -129,12 +129,20 @@ static struct i2c_driver f75375_legacy_d
.detach_client = f75375_detach_client,
};
+static const struct i2c_device_id f75375_id[] = {
+ { "f75373", f75373 },
+ { "f75375", f75375 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, f75375_id);
+
static struct i2c_driver f75375_driver = {
.driver = {
.name = "f75375",
},
.probe = f75375_probe,
.remove = f75375_remove,
+ .id_table = f75375_id,
};
static inline int f75375_read8(struct i2c_client *client, u8 reg)
@@ -645,15 +653,7 @@ static int f75375_probe(struct i2c_clien
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->update_lock);
-
- if (strcmp(client->name, "f75375") == 0)
- data->kind = f75375;
- else if (strcmp(client->name, "f75373") == 0)
- data->kind = f75373;
- else {
- dev_err(&client->dev, "Unsupported device: %s\n", client->name);
- return -ENODEV;
- }
+ data->kind = id->driver_data;
if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group)))
goto exit_free;
@@ -714,6 +714,7 @@ static int f75375_detect(struct i2c_adap
u8 version = 0;
int err = 0;
const char *name = "";
+ struct i2c_device_id id;
if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) {
err = -ENOMEM;
@@ -750,7 +751,9 @@ static int f75375_detect(struct i2c_adap
if ((err = i2c_attach_client(client)))
goto exit_free;
- if ((err = f75375_probe(client, NULL)) < 0)
+ strlcpy(id.name, name, I2C_NAME_SIZE);
+ id.driver_data = kind;
+ if ((err = f75375_probe(client, &id)) < 0)
goto exit_detach;
return 0;
--- linux-2.6.26-rc0.orig/drivers/i2c/busses/i2c-taos-evm.c 2008-04-28 22:58:32.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/busses/i2c-taos-evm.c 2008-04-29 08:55:08.000000000 +0200
@@ -51,7 +51,6 @@ struct taos_data {
/* TAOS TSL2550 EVM */
static struct i2c_board_info tsl2550_info = {
I2C_BOARD_INFO("tsl2550", 0x39),
- .type = "tsl2550",
};
/* Instantiate i2c devices based on the adapter name */
@@ -59,7 +58,7 @@ static struct i2c_client *taos_instantia
{
if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) {
dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n",
- tsl2550_info.driver_name, tsl2550_info.addr);
+ tsl2550_info.type, tsl2550_info.addr);
return i2c_new_device(adapter, &tsl2550_info);
}
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/ds1682.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/ds1682.c 2008-04-29 08:55:08.000000000 +0200
@@ -235,12 +235,19 @@ static int ds1682_remove(struct i2c_clie
return 0;
}
+static const struct i2c_device_id ds1682_id[] = {
+ { "ds1682", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ds1682_id);
+
static struct i2c_driver ds1682_driver = {
.driver = {
.name = "ds1682",
},
.probe = ds1682_probe,
.remove = ds1682_remove,
+ .id_table = ds1682_id,
};
static int __init ds1682_init(void)
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/menelaus.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/menelaus.c 2008-04-29 08:55:08.000000000 +0200
@@ -1243,12 +1243,19 @@ static int __exit menelaus_remove(struct
return 0;
}
+static const struct i2c_device_id menelaus_id[] = {
+ { "menelaus", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, menelaus_id);
+
static struct i2c_driver menelaus_i2c_driver = {
.driver = {
.name = DRIVER_NAME,
},
.probe = menelaus_probe,
.remove = __exit_p(menelaus_remove),
+ .id_table = menelaus_id,
};
static int __init menelaus_init(void)
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/tps65010.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/tps65010.c 2008-04-29 08:55:08.000000000 +0200
@@ -64,7 +64,6 @@ static struct i2c_driver tps65010_driver
* as part of board setup by a bootloader.
*/
enum tps_model {
- TPS_UNKNOWN = 0,
TPS65010,
TPS65011,
TPS65012,
@@ -554,20 +553,7 @@ static int tps65010_probe(struct i2c_cli
mutex_init(&tps->lock);
INIT_DELAYED_WORK(&tps->work, tps65010_work);
tps->client = client;
-
- if (strcmp(client->name, "tps65010") == 0)
- tps->model = TPS65010;
- else if (strcmp(client->name, "tps65011") == 0)
- tps->model = TPS65011;
- else if (strcmp(client->name, "tps65012") == 0)
- tps->model = TPS65012;
- else if (strcmp(client->name, "tps65013") == 0)
- tps->model = TPS65013;
- else {
- dev_warn(&client->dev, "unknown chip '%s'\n", client->name);
- status = -ENODEV;
- goto fail1;
- }
+ tps->model = id->driver_data;
/* the IRQ is active low, but many gpio lines can't support that
* so this driver uses falling-edge triggers instead.
@@ -596,9 +582,6 @@ static int tps65010_probe(struct i2c_cli
case TPS65012:
tps->por = 1;
break;
- case TPS_UNKNOWN:
- printk(KERN_WARNING "%s: unknown TPS chip\n", DRIVER_NAME);
- break;
/* else CHGCONFIG.POR is replaced by AUA, enabling a WAIT mode */
}
tps->chgconf = i2c_smbus_read_byte_data(client, TPS_CHGCONFIG);
@@ -685,12 +668,22 @@ fail1:
return status;
}
+static const struct i2c_device_id tps65010_id[] = {
+ { "tps65010", TPS65010 },
+ { "tps65011", TPS65011 },
+ { "tps65012", TPS65012 },
+ { "tps65013", TPS65013 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tps65010_id);
+
static struct i2c_driver tps65010_driver = {
.driver = {
.name = "tps65010",
},
.probe = tps65010_probe,
.remove = __exit_p(tps65010_remove),
+ .id_table = tps65010_id,
};
/*-------------------------------------------------------------------------*/
--- linux-2.6.26-rc0.orig/drivers/i2c/chips/tsl2550.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/i2c/chips/tsl2550.c 2008-04-29 08:55:08.000000000 +0200
@@ -452,6 +452,12 @@ static int tsl2550_resume(struct i2c_cli
#endif /* CONFIG_PM */
+static const struct i2c_device_id tsl2550_id[] = {
+ { "tsl2550", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tsl2550_id);
+
static struct i2c_driver tsl2550_driver = {
.driver = {
.name = TSL2550_DRV_NAME,
@@ -461,6 +467,7 @@ static struct i2c_driver tsl2550_driver
.resume = tsl2550_resume,
.probe = tsl2550_probe,
.remove = __devexit_p(tsl2550_remove),
+ .id_table = tsl2550_id,
};
static int __init tsl2550_init(void)
--- linux-2.6.26-rc0.orig/drivers/media/video/mt9m001.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/mt9m001.c 2008-04-29 08:55:08.000000000 +0200
@@ -697,12 +697,19 @@ static int mt9m001_remove(struct i2c_cli
return 0;
}
+static const struct i2c_device_id mt9m001_id[] = {
+ { "mt9m001", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mt9m001_id);
+
static struct i2c_driver mt9m001_i2c_driver = {
.driver = {
.name = "mt9m001",
},
.probe = mt9m001_probe,
.remove = mt9m001_remove,
+ .id_table = mt9m001_id,
};
static int __init mt9m001_mod_init(void)
--- linux-2.6.26-rc0.orig/drivers/media/video/mt9v022.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/media/video/mt9v022.c 2008-04-29 08:55:08.000000000 +0200
@@ -819,12 +819,19 @@ static int mt9v022_remove(struct i2c_cli
return 0;
}
+static const struct i2c_device_id mt9v022_id[] = {
+ { "mt9v022", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mt9v022_id);
+
static struct i2c_driver mt9v022_i2c_driver = {
.driver = {
.name = "mt9v022",
},
.probe = mt9v022_probe,
.remove = mt9v022_remove,
+ .id_table = mt9v022_id,
};
static int __init mt9v022_mod_init(void)
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-ds1307.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-ds1307.c 2008-04-29 08:55:08.000000000 +0200
@@ -99,45 +99,38 @@ struct ds1307 {
};
struct chip_desc {
- char name[9];
unsigned nvram56:1;
unsigned alarm:1;
- enum ds_type type;
};
-static const struct chip_desc chips[] = { {
- .name = "ds1307",
- .type = ds_1307,
+static const struct chip_desc chips[] = {
+[ds_1307] = {
.nvram56 = 1,
-}, {
- .name = "ds1337",
- .type = ds_1337,
+},
+[ds_1337] = {
.alarm = 1,
-}, {
- .name = "ds1338",
- .type = ds_1338,
+},
+[ds_1338] = {
.nvram56 = 1,
-}, {
- .name = "ds1339",
- .type = ds_1339,
+},
+[ds_1339] = {
.alarm = 1,
-}, {
- .name = "ds1340",
- .type = ds_1340,
-}, {
- .name = "m41t00",
- .type = m41t00,
+},
+[ds_1340] = {
+},
+[m41t00] = {
}, };
-static inline const struct chip_desc *find_chip(const char *s)
-{
- unsigned i;
-
- for (i = 0; i < ARRAY_SIZE(chips); i++)
- if (strnicmp(s, chips[i].name, sizeof chips[i].name) == 0)
- return &chips[i];
- return NULL;
-}
+static const struct i2c_device_id ds1307_id[] = {
+ { "ds1307", ds_1307 },
+ { "ds1337", ds_1337 },
+ { "ds1338", ds_1338 },
+ { "ds1339", ds_1339 },
+ { "ds1340", ds_1340 },
+ { "m41t00", m41t00 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ds1307_id);
static int ds1307_get_time(struct device *dev, struct rtc_time *t)
{
@@ -332,16 +325,9 @@ static int __devinit ds1307_probe(struct
struct ds1307 *ds1307;
int err = -ENODEV;
int tmp;
- const struct chip_desc *chip;
+ const struct chip_desc *chip = &chips[id->driver_data];
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- chip = find_chip(client->name);
- if (!chip) {
- dev_err(&client->dev, "unknown chip type '%s'\n",
- client->name);
- return -ENODEV;
- }
-
if (!i2c_check_functionality(adapter,
I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
return -EIO;
@@ -362,7 +348,7 @@ static int __devinit ds1307_probe(struct
ds1307->msg[1].len = sizeof(ds1307->regs);
ds1307->msg[1].buf = ds1307->regs;
- ds1307->type = chip->type;
+ ds1307->type = id->driver_data;
switch (ds1307->type) {
case ds_1337:
@@ -551,6 +537,7 @@ static struct i2c_driver ds1307_driver =
},
.probe = ds1307_probe,
.remove = __devexit_p(ds1307_remove),
+ .id_table = ds1307_id,
};
static int __init ds1307_init(void)
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-ds1374.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-ds1374.c 2008-04-29 08:55:08.000000000 +0200
@@ -41,6 +41,12 @@
#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */
#define DS1374_REG_TCR 0x09 /* Trickle Charge */
+static const struct i2c_device_id ds1374_id[] = {
+ { "ds1374", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ds1374_id);
+
struct ds1374 {
struct i2c_client *client;
struct rtc_device *rtc;
@@ -430,6 +436,7 @@ static struct i2c_driver ds1374_driver =
},
.probe = ds1374_probe,
.remove = __devexit_p(ds1374_remove),
+ .id_table = ds1374_id,
};
static int __init ds1374_init(void)
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-isl1208.c 2008-04-29 08:50:01.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-isl1208.c 2008-04-29 09:06:31.000000000 +0200
@@ -545,12 +545,19 @@ isl1208_remove(struct i2c_client *client
return 0;
}
+static const struct i2c_device_id isl1208_id[] = {
+ { "isl1208", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, isl1208_id);
+
static struct i2c_driver isl1208_driver = {
.driver = {
.name = "rtc-isl1208",
},
.probe = isl1208_probe,
.remove = isl1208_remove,
+ .id_table = isl1208_id,
};
static int __init
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-m41t80.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-m41t80.c 2008-04-29 08:55:08.000000000 +0200
@@ -60,48 +60,21 @@
#define DRV_VERSION "0.05"
-struct m41t80_chip_info {
- const char *name;
- u8 features;
-};
-
-static const struct m41t80_chip_info m41t80_chip_info_tbl[] = {
- {
- .name = "m41t80",
- .features = 0,
- },
- {
- .name = "m41t81",
- .features = M41T80_FEATURE_HT,
- },
- {
- .name = "m41t81s",
- .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
- },
- {
- .name = "m41t82",
- .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
- },
- {
- .name = "m41t83",
- .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
- },
- {
- .name = "m41st84",
- .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
- },
- {
- .name = "m41st85",
- .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
- },
- {
- .name = "m41st87",
- .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
- },
+static const struct i2c_device_id m41t80_id[] = {
+ { "m41t80", 0 },
+ { "m41t81", M41T80_FEATURE_HT },
+ { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+ { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+ { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+ { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+ { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+ { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+ { }
};
+MODULE_DEVICE_TABLE(i2c, m41t80_id);
struct m41t80_data {
- const struct m41t80_chip_info *chip;
+ u8 features;
struct rtc_device *rtc;
};
@@ -208,7 +181,7 @@ static int m41t80_rtc_proc(struct device
struct m41t80_data *clientdata = i2c_get_clientdata(client);
u8 reg;
- if (clientdata->chip->features & M41T80_FEATURE_BL) {
+ if (clientdata->features & M41T80_FEATURE_BL) {
reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
seq_printf(seq, "battery\t\t: %s\n",
(reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
@@ -759,10 +732,9 @@ static struct notifier_block wdt_notifie
static int m41t80_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- int i, rc = 0;
+ int rc = 0;
struct rtc_device *rtc = NULL;
struct rtc_time tm;
- const struct m41t80_chip_info *chip;
struct m41t80_data *clientdata = NULL;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
@@ -774,19 +746,6 @@ static int m41t80_probe(struct i2c_clien
dev_info(&client->dev,
"chip found, driver version " DRV_VERSION "\n");
- chip = NULL;
- for (i = 0; i < ARRAY_SIZE(m41t80_chip_info_tbl); i++) {
- if (!strcmp(m41t80_chip_info_tbl[i].name, client->name)) {
- chip = &m41t80_chip_info_tbl[i];
- break;
- }
- }
- if (!chip) {
- dev_err(&client->dev, "%s is not supported\n", client->name);
- rc = -ENODEV;
- goto exit;
- }
-
clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL);
if (!clientdata) {
rc = -ENOMEM;
@@ -802,7 +761,7 @@ static int m41t80_probe(struct i2c_clien
}
clientdata->rtc = rtc;
- clientdata->chip = chip;
+ clientdata->features = id->driver_data;
i2c_set_clientdata(client, clientdata);
/* Make sure HT (Halt Update) bit is cleared */
@@ -811,7 +770,7 @@ static int m41t80_probe(struct i2c_clien
goto ht_err;
if (rc & M41T80_ALHOUR_HT) {
- if (chip->features & M41T80_FEATURE_HT) {
+ if (clientdata->features & M41T80_FEATURE_HT) {
m41t80_get_datetime(client, &tm);
dev_info(&client->dev, "HT bit was set!\n");
dev_info(&client->dev,
@@ -843,7 +802,7 @@ static int m41t80_probe(struct i2c_clien
goto exit;
#ifdef CONFIG_RTC_DRV_M41T80_WDT
- if (chip->features & M41T80_FEATURE_HT) {
+ if (clientdata->features & M41T80_FEATURE_HT) {
rc = misc_register(&wdt_dev);
if (rc)
goto exit;
@@ -879,7 +838,7 @@ static int m41t80_remove(struct i2c_clie
struct rtc_device *rtc = clientdata->rtc;
#ifdef CONFIG_RTC_DRV_M41T80_WDT
- if (clientdata->chip->features & M41T80_FEATURE_HT) {
+ if (clientdata->features & M41T80_FEATURE_HT) {
misc_deregister(&wdt_dev);
unregister_reboot_notifier(&wdt_notifier);
}
@@ -897,6 +856,7 @@ static struct i2c_driver m41t80_driver =
},
.probe = m41t80_probe,
.remove = m41t80_remove,
+ .id_table = m41t80_id,
};
static int __init m41t80_rtc_init(void)
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-pcf8563.c 2008-04-29 08:49:41.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-pcf8563.c 2008-04-29 09:07:17.000000000 +0200
@@ -300,12 +300,19 @@ static int pcf8563_remove(struct i2c_cli
return 0;
}
+static const struct i2c_device_id pcf8563_id[] = {
+ { "pcf8563", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, pcf8563_id);
+
static struct i2c_driver pcf8563_driver = {
.driver = {
.name = "rtc-pcf8563",
},
.probe = pcf8563_probe,
.remove = pcf8563_remove,
+ .id_table = pcf8563_id,
};
static int __init pcf8563_init(void)
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-rs5c372.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-rs5c372.c 2008-04-29 08:56:12.000000000 +0200
@@ -69,6 +69,15 @@ enum rtc_type {
rtc_rv5c387a,
};
+static const struct i2c_device_id rs5c372_id[] = {
+ { "rs5c372a", rtc_rs5c372a },
+ { "rs5c372b", rtc_rs5c372b },
+ { "rv5c386", rtc_rv5c386 },
+ { "rv5c387a", rtc_rv5c387a },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rs5c372_id);
+
/* REVISIT: this assumes that:
* - we're in the 21st century, so it's safe to ignore the century
* bit for rv5c38[67] (REG_MONTH bit 7);
@@ -515,6 +524,7 @@ static int rs5c372_probe(struct i2c_clie
rs5c372->client = client;
i2c_set_clientdata(client, rs5c372);
+ rs5c372->type = id->driver_data;
/* we read registers 0x0f then 0x00-0x0f; skip the first one */
rs5c372->regs = &rs5c372->buf[1];
@@ -523,19 +533,6 @@ static int rs5c372_probe(struct i2c_clie
if (err < 0)
goto exit_kfree;
- if (strcmp(client->name, "rs5c372a") == 0)
- rs5c372->type = rtc_rs5c372a;
- else if (strcmp(client->name, "rs5c372b") == 0)
- rs5c372->type = rtc_rs5c372b;
- else if (strcmp(client->name, "rv5c386") == 0)
- rs5c372->type = rtc_rv5c386;
- else if (strcmp(client->name, "rv5c387a") == 0)
- rs5c372->type = rtc_rv5c387a;
- else {
- rs5c372->type = rtc_rs5c372b;
- dev_warn(&client->dev, "assuming rs5c372b\n");
- }
-
/* clock may be set for am/pm or 24 hr time */
switch (rs5c372->type) {
case rtc_rs5c372a:
@@ -652,6 +649,7 @@ static struct i2c_driver rs5c372_driver
},
.probe = rs5c372_probe,
.remove = rs5c372_remove,
+ .id_table = rs5c372_id,
};
static __init int rs5c372_init(void)
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-s35390a.c 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-s35390a.c 2008-04-29 08:55:08.000000000 +0200
@@ -34,6 +34,12 @@
#define S35390A_FLAG_RESET 0x80
#define S35390A_FLAG_TEST 0x01
+static const struct i2c_device_id s35390a_id[] = {
+ { "s35390a", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, s35390a_id);
+
struct s35390a {
struct i2c_client *client[8];
struct rtc_device *rtc;
@@ -297,6 +303,7 @@ static struct i2c_driver s35390a_driver
},
.probe = s35390a_probe,
.remove = s35390a_remove,
+ .id_table = s35390a_id,
};
static int __init s35390a_rtc_init(void)
--- linux-2.6.26-rc0.orig/drivers/rtc/rtc-x1205.c 2008-04-29 08:48:52.000000000 +0200
+++ linux-2.6.26-rc0/drivers/rtc/rtc-x1205.c 2008-04-29 09:05:26.000000000 +0200
@@ -553,12 +553,19 @@ static int x1205_remove(struct i2c_clien
return 0;
}
+static const struct i2c_device_id x1205_id[] = {
+ { "x1205", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, x1205_id);
+
static struct i2c_driver x1205_driver = {
.driver = {
.name = "rtc-x1205",
},
.probe = x1205_probe,
.remove = x1205_remove,
+ .id_table = x1205_id,
};
static int __init x1205_init(void)
--- linux-2.6.26-rc0.orig/include/linux/i2c.h 2008-04-29 08:37:43.000000000 +0200
+++ linux-2.6.26-rc0/include/linux/i2c.h 2008-04-29 08:55:08.000000000 +0200
@@ -229,17 +229,17 @@ struct i2c_board_info {
};
/**
- * I2C_BOARD_INFO - macro used to list an i2c device and its driver
- * @driver: identifies the driver to use with the device
+ * I2C_BOARD_INFO - macro used to list an i2c device and its address
+ * @dev_type: identifies the device type
* @dev_addr: the device's address on the bus.
*
* This macro initializes essential fields of a struct i2c_board_info,
* declaring what has been provided on a particular board. Optional
- * fields (such as the chip type, its associated irq, or device-specific
- * platform_data) are provided using conventional syntax.
+ * fields (such as associated irq, or device-specific platform_data)
+ * are provided using conventional syntax.
*/
-#define I2C_BOARD_INFO(driver,dev_addr) \
- .driver_name = (driver), .addr = (dev_addr)
+#define I2C_BOARD_INFO(dev_type,dev_addr) \
+ .type = (dev_type), .addr = (dev_addr)
/* Add-on boards should register/unregister their devices; e.g. a board
--
Jean Delvare
^ permalink raw reply
* [git pull] Please pull powerpc.git master branch
From: Paul Mackerras @ 2008-04-29 11:29 UTC (permalink / raw)
To: torvalds; +Cc: linuxppc-dev, akpm, linux-kernel
Linus,
Please do:
git pull \
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git master=
There are 14 commits there that Andrew Morton sent to me to merge,
from Badari Pulavarty (memory hot-remove stuff) and Zhang Wei (RapidIO
patches). Plus there are 5 other powerpc-related patches: a patch
from me adding a fast endian-switch system call, a patch from Kumar
Gala that lets 32-bit use separate stacks for hard and soft IRQs like
64-bit already does, a build fix from Tony Breeds, a patch from me to
make powerpc build OK if inline doesn't mean __always_inline, and a
thermal driver for one of the last G5 powermac models.
Thanks,
Paul.
Badari Pulavarty (3):
[POWERPC] Hotplug memory remove notifications for powerpc
[POWERPC] Update lmb data structures for hotplug memory add/remov=
e
[POWERPC] Provide walk_memory_resource() for powerpc
Kumar Gala (1):
[POWERPC] Add IRQSTACKS support on ppc32
Paul Mackerras (2):
[POWERPC] Add fast little-endian switch system call
[POWERPC] Use __always_inline for xchg* and cmpxchg*
Tony Breeds (1):
[POWERPC] Fix building of pmac32 when CONFIG_NVRAM=3Dm
Zhang Wei (11):
[RAPIDIO] Change RIO function mpc85xx_ to fsl_
[RAPIDIO] Add RapidIO option to kernel configuration
[RAPIDIO] Move include/asm-ppc/rio.h to asm-powerpc
[RAPIDIO] Add RapidIO multi mport support
[RAPIDIO] Add OF-tree support to RapidIO controller driver
[RAPIDIO] Auto-probe the RapidIO system size
[RAPIDIO] Add RapidIO node into MPC8641HPCN dts file
[RAPIDIO] Add RapidIO node probing into MPC86xx_HPCN board id tab=
le
[RAPIDIO] Add serial RapidIO controller support, which includes M=
PC8548, MPC8641
[RAPIDIO] Add RapidIO connection info print out and re-training f=
or broken connections
[RAPIDIO] Change RapidIO doorbell source and target ID field to 1=
6-bit
=C9tienne Bersac (1):
[POWERPC] windfarm: Add PowerMac 12,1 support
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox