Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

Subsystems: aoa (apple onboard audio) alsa driver, sound, the rest

12 messages, 2 authors, 2012-06-18 · open the first message on its own page

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Andreas Schwab <hidden>
Date: 2012-06-09 13:59:03

That breaks the tas3004 driver (and most likely the pcm3052 driver as
well), since it wants to create its own i2c device.  I'm using the
attached patch as a workaround (only tas3004 driver tested on iBook G4),
but that needs to move the workarounds for the older systems that don't
have proper compatible properties somewhere else, which I don't know
where.

Andreas.

---
 sound/aoa/codecs/onyx.c |   75 ++------------------------------------------
 sound/aoa/codecs/tas.c  |   80 ++---------------------------------------------
 2 files changed, 6 insertions(+), 149 deletions(-)
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 270790d..4cedc69 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -997,45 +997,10 @@ static void onyx_exit_codec(struct aoa_codec *codec)
 	onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
 }
 
-static int onyx_create(struct i2c_adapter *adapter,
-		       struct device_node *node,
-		       int addr)
-{
-	struct i2c_board_info info;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, "aoa_codec_onyx", I2C_NAME_SIZE);
-	info.addr = addr;
-	info.platform_data = node;
-	client = i2c_new_device(adapter, &info);
-	if (!client)
-		return -ENODEV;
-
-	/*
-	 * We know the driver is already loaded, so the device should be
-	 * already bound. If not it means binding failed, which suggests
-	 * the device doesn't really exist and should be deleted.
-	 * Ideally this would be replaced by better checks _before_
-	 * instantiating the device.
-	 */
-	if (!client->driver) {
-		i2c_unregister_device(client);
-		return -ENODEV;
-	}
-
-	/*
-	 * Let i2c-core delete that device on driver removal.
-	 * This is safe because i2c-core holds the core_lock mutex for us.
-	 */
-	list_add_tail(&client->detected, &client->driver->clients);
-	return 0;
-}
-
 static int onyx_i2c_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-	struct device_node *node = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct onyx *onyx;
 	u8 dummy;
 
@@ -1071,40 +1036,6 @@ static int onyx_i2c_probe(struct i2c_client *client,
 	return -ENODEV;
 }
 
-static int onyx_i2c_attach(struct i2c_adapter *adapter)
-{
-	struct device_node *busnode, *dev = NULL;
-	struct pmac_i2c_bus *bus;
-
-	bus = pmac_i2c_adapter_to_bus(adapter);
-	if (bus == NULL)
-		return -ENODEV;
-	busnode = pmac_i2c_get_bus_node(bus);
-
-	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
-		if (of_device_is_compatible(dev, "pcm3052")) {
-			const u32 *addr;
-			printk(KERN_DEBUG PFX "found pcm3052\n");
-			addr = of_get_property(dev, "reg", NULL);
-			if (!addr)
-				return -ENODEV;
-			return onyx_create(adapter, dev, (*addr)>>1);
-		}
-	}
-
-	/* if that didn't work, try desperate mode for older
-	 * machines that have stuff missing from the device tree */
-
-	if (!of_device_is_compatible(busnode, "k2-i2c"))
-		return -ENODEV;
-
-	printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
-	/* probe both possible addresses for the onyx chip */
-	if (onyx_create(adapter, NULL, 0x46) == 0)
-		return 0;
-	return onyx_create(adapter, NULL, 0x47);
-}
-
 static int onyx_i2c_remove(struct i2c_client *client)
 {
 	struct onyx *onyx = i2c_get_clientdata(client);
@@ -1117,16 +1048,16 @@ static int onyx_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id onyx_i2c_id[] = {
-	{ "aoa_codec_onyx", 0 },
+	{ "MAC,pcm3052", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
 
 static struct i2c_driver onyx_driver = {
 	.driver = {
 		.name = "aoa_codec_onyx",
 		.owner = THIS_MODULE,
 	},
-	.attach_adapter = onyx_i2c_attach,
 	.probe = onyx_i2c_probe,
 	.remove = onyx_i2c_remove,
 	.id_table = onyx_i2c_id,
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 8e63d1f..c491ae0 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -883,43 +883,10 @@ static void tas_exit_codec(struct aoa_codec *codec)
 }
 
 
-static int tas_create(struct i2c_adapter *adapter,
-		       struct device_node *node,
-		       int addr)
-{
-	struct i2c_board_info info;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE);
-	info.addr = addr;
-	info.platform_data = node;
-
-	client = i2c_new_device(adapter, &info);
-	if (!client)
-		return -ENODEV;
-	/*
-	 * We know the driver is already loaded, so the device should be
-	 * already bound. If not it means binding failed, and then there
-	 * is no point in keeping the device instantiated.
-	 */
-	if (!client->driver) {
-		i2c_unregister_device(client);
-		return -ENODEV;
-	}
-
-	/*
-	 * Let i2c-core delete that device on driver removal.
-	 * This is safe because i2c-core holds the core_lock mutex for us.
-	 */
-	list_add_tail(&client->detected, &client->driver->clients);
-	return 0;
-}
-
 static int tas_i2c_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
-	struct device_node *node = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct tas *tas;
 
 	tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
@@ -953,47 +920,6 @@ static int tas_i2c_probe(struct i2c_client *client,
 	return -EINVAL;
 }
 
-static int tas_i2c_attach(struct i2c_adapter *adapter)
-{
-	struct device_node *busnode, *dev = NULL;
-	struct pmac_i2c_bus *bus;
-
-	bus = pmac_i2c_adapter_to_bus(adapter);
-	if (bus == NULL)
-		return -ENODEV;
-	busnode = pmac_i2c_get_bus_node(bus);
-
-	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
-		if (of_device_is_compatible(dev, "tas3004")) {
-			const u32 *addr;
-			printk(KERN_DEBUG PFX "found tas3004\n");
-			addr = of_get_property(dev, "reg", NULL);
-			if (!addr)
-				continue;
-			return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
-		}
-		/* older machines have no 'codec' node with a 'compatible'
-		 * property that says 'tas3004', they just have a 'deq'
-		 * node without any such property... */
-		if (strcmp(dev->name, "deq") == 0) {
-			const u32 *_addr;
-			u32 addr;
-			printk(KERN_DEBUG PFX "found 'deq' node\n");
-			_addr = of_get_property(dev, "i2c-address", NULL);
-			if (!_addr)
-				continue;
-			addr = ((*_addr) >> 1) & 0x7f;
-			/* now, if the address doesn't match any of the two
-			 * that a tas3004 can have, we cannot handle this.
-			 * I doubt it ever happens but hey. */
-			if (addr != 0x34 && addr != 0x35)
-				continue;
-			return tas_create(adapter, dev, addr);
-		}
-	}
-	return -ENODEV;
-}
-
 static int tas_i2c_remove(struct i2c_client *client)
 {
 	struct tas *tas = i2c_get_clientdata(client);
@@ -1011,16 +937,16 @@ static int tas_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tas_i2c_id[] = {
-	{ "aoa_codec_tas", 0 },
+	{ "MAC,tas3004", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c,tas_i2c_id);
 
 static struct i2c_driver tas_driver = {
 	.driver = {
 		.name = "aoa_codec_tas",
 		.owner = THIS_MODULE,
 	},
-	.attach_adapter = tas_i2c_attach,
 	.probe = tas_i2c_probe,
 	.remove = tas_i2c_remove,
 	.id_table = tas_i2c_id,
-- 
1.7.10.4


-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2012-06-09 22:11:40

On Sat, 2012-06-09 at 15:58 +0200, Andreas Schwab wrote:
That breaks the tas3004 driver (and most likely the pcm3052 driver as
well), since it wants to create its own i2c device.  I'm using the
attached patch as a workaround (only tas3004 driver tested on iBook G4),
but that needs to move the workarounds for the older systems that don't
have proper compatible properties somewhere else, which I don't know
where.
Should we keep the tas_create method for those ? We could have some code
in the aoa core file that calls those "fixups" to create missing
devices...

Cheers,
Ben.
quoted hunk
Andreas.

---
 sound/aoa/codecs/onyx.c |   75 ++------------------------------------------
 sound/aoa/codecs/tas.c  |   80 ++---------------------------------------------
 2 files changed, 6 insertions(+), 149 deletions(-)
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 270790d..4cedc69 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -997,45 +997,10 @@ static void onyx_exit_codec(struct aoa_codec *codec)
 	onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
 }
 
-static int onyx_create(struct i2c_adapter *adapter,
-		       struct device_node *node,
-		       int addr)
-{
-	struct i2c_board_info info;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, "aoa_codec_onyx", I2C_NAME_SIZE);
-	info.addr = addr;
-	info.platform_data = node;
-	client = i2c_new_device(adapter, &info);
-	if (!client)
-		return -ENODEV;
-
-	/*
-	 * We know the driver is already loaded, so the device should be
-	 * already bound. If not it means binding failed, which suggests
-	 * the device doesn't really exist and should be deleted.
-	 * Ideally this would be replaced by better checks _before_
-	 * instantiating the device.
-	 */
-	if (!client->driver) {
-		i2c_unregister_device(client);
-		return -ENODEV;
-	}
-
-	/*
-	 * Let i2c-core delete that device on driver removal.
-	 * This is safe because i2c-core holds the core_lock mutex for us.
-	 */
-	list_add_tail(&client->detected, &client->driver->clients);
-	return 0;
-}
-
 static int onyx_i2c_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-	struct device_node *node = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct onyx *onyx;
 	u8 dummy;
 
@@ -1071,40 +1036,6 @@ static int onyx_i2c_probe(struct i2c_client *client,
 	return -ENODEV;
 }
 
-static int onyx_i2c_attach(struct i2c_adapter *adapter)
-{
-	struct device_node *busnode, *dev = NULL;
-	struct pmac_i2c_bus *bus;
-
-	bus = pmac_i2c_adapter_to_bus(adapter);
-	if (bus == NULL)
-		return -ENODEV;
-	busnode = pmac_i2c_get_bus_node(bus);
-
-	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
-		if (of_device_is_compatible(dev, "pcm3052")) {
-			const u32 *addr;
-			printk(KERN_DEBUG PFX "found pcm3052\n");
-			addr = of_get_property(dev, "reg", NULL);
-			if (!addr)
-				return -ENODEV;
-			return onyx_create(adapter, dev, (*addr)>>1);
-		}
-	}
-
-	/* if that didn't work, try desperate mode for older
-	 * machines that have stuff missing from the device tree */
-
-	if (!of_device_is_compatible(busnode, "k2-i2c"))
-		return -ENODEV;
-
-	printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
-	/* probe both possible addresses for the onyx chip */
-	if (onyx_create(adapter, NULL, 0x46) == 0)
-		return 0;
-	return onyx_create(adapter, NULL, 0x47);
-}
-
 static int onyx_i2c_remove(struct i2c_client *client)
 {
 	struct onyx *onyx = i2c_get_clientdata(client);
@@ -1117,16 +1048,16 @@ static int onyx_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id onyx_i2c_id[] = {
-	{ "aoa_codec_onyx", 0 },
+	{ "MAC,pcm3052", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
 
 static struct i2c_driver onyx_driver = {
 	.driver = {
 		.name = "aoa_codec_onyx",
 		.owner = THIS_MODULE,
 	},
-	.attach_adapter = onyx_i2c_attach,
 	.probe = onyx_i2c_probe,
 	.remove = onyx_i2c_remove,
 	.id_table = onyx_i2c_id,
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 8e63d1f..c491ae0 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -883,43 +883,10 @@ static void tas_exit_codec(struct aoa_codec *codec)
 }
 

-static int tas_create(struct i2c_adapter *adapter,
-		       struct device_node *node,
-		       int addr)
-{
-	struct i2c_board_info info;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE);
-	info.addr = addr;
-	info.platform_data = node;
-
-	client = i2c_new_device(adapter, &info);
-	if (!client)
-		return -ENODEV;
-	/*
-	 * We know the driver is already loaded, so the device should be
-	 * already bound. If not it means binding failed, and then there
-	 * is no point in keeping the device instantiated.
-	 */
-	if (!client->driver) {
-		i2c_unregister_device(client);
-		return -ENODEV;
-	}
-
-	/*
-	 * Let i2c-core delete that device on driver removal.
-	 * This is safe because i2c-core holds the core_lock mutex for us.
-	 */
-	list_add_tail(&client->detected, &client->driver->clients);
-	return 0;
-}
-
 static int tas_i2c_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
-	struct device_node *node = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct tas *tas;
 
 	tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
@@ -953,47 +920,6 @@ static int tas_i2c_probe(struct i2c_client *client,
 	return -EINVAL;
 }
 
-static int tas_i2c_attach(struct i2c_adapter *adapter)
-{
-	struct device_node *busnode, *dev = NULL;
-	struct pmac_i2c_bus *bus;
-
-	bus = pmac_i2c_adapter_to_bus(adapter);
-	if (bus == NULL)
-		return -ENODEV;
-	busnode = pmac_i2c_get_bus_node(bus);
-
-	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
-		if (of_device_is_compatible(dev, "tas3004")) {
-			const u32 *addr;
-			printk(KERN_DEBUG PFX "found tas3004\n");
-			addr = of_get_property(dev, "reg", NULL);
-			if (!addr)
-				continue;
-			return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
-		}
-		/* older machines have no 'codec' node with a 'compatible'
-		 * property that says 'tas3004', they just have a 'deq'
-		 * node without any such property... */
-		if (strcmp(dev->name, "deq") == 0) {
-			const u32 *_addr;
-			u32 addr;
-			printk(KERN_DEBUG PFX "found 'deq' node\n");
-			_addr = of_get_property(dev, "i2c-address", NULL);
-			if (!_addr)
-				continue;
-			addr = ((*_addr) >> 1) & 0x7f;
-			/* now, if the address doesn't match any of the two
-			 * that a tas3004 can have, we cannot handle this.
-			 * I doubt it ever happens but hey. */
-			if (addr != 0x34 && addr != 0x35)
-				continue;
-			return tas_create(adapter, dev, addr);
-		}
-	}
-	return -ENODEV;
-}
-
 static int tas_i2c_remove(struct i2c_client *client)
 {
 	struct tas *tas = i2c_get_clientdata(client);
@@ -1011,16 +937,16 @@ static int tas_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tas_i2c_id[] = {
-	{ "aoa_codec_tas", 0 },
+	{ "MAC,tas3004", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c,tas_i2c_id);
 
 static struct i2c_driver tas_driver = {
 	.driver = {
 		.name = "aoa_codec_tas",
 		.owner = THIS_MODULE,
 	},
-	.attach_adapter = tas_i2c_attach,
 	.probe = tas_i2c_probe,
 	.remove = tas_i2c_remove,
 	.id_table = tas_i2c_id,
-- 
1.7.10.4

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Andreas Schwab <hidden>
Date: 2012-06-09 22:30:23

Benjamin Herrenschmidt [off-list ref] writes:
Should we keep the tas_create method for those ? We could have some code
in the aoa core file that calls those "fixups" to create missing
devices...
I'm not sure if the function is needed, if the device can be created in
i2c_powermac_register_devices.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2012-06-09 22:36:09

On Sun, 2012-06-10 at 00:30 +0200, Andreas Schwab wrote:
quoted
Should we keep the tas_create method for those ? We could have some code
in the aoa core file that calls those "fixups" to create missing
devices...
I'm not sure if the function is needed, if the device can be created in
i2c_powermac_register_devices.
But it doesn't have a device-node ... does it ? Which machine is this
btw ? Can you shoot me privately the device-tree ? That will help me
figure out what exactly needs to be done.

Thanks !

Cheers,
Ben.

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Andreas Schwab <hidden>
Date: 2012-06-09 22:59:22

Benjamin Herrenschmidt [off-list ref] writes:
On Sun, 2012-06-10 at 00:30 +0200, Andreas Schwab wrote:
quoted
quoted
Should we keep the tas_create method for those ? We could have some code
in the aoa core file that calls those "fixups" to create missing
devices...
I'm not sure if the function is needed, if the device can be created in
i2c_powermac_register_devices.
But it doesn't have a device-node ... does it ? Which machine is this
btw ?
It's a PowerMac G5.  During booting I see this:

PowerMac i2c bus pmu 2 registered
PowerMac i2c bus pmu 1 registered
PowerMac i2c bus mac-io 0 registered
i2c i2c-5: i2c-powermac: modalias failure on /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a
i2c i2c-5: i2c-powermac: invalid reg on /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/i2c-modem
PowerMac i2c bus u3 1 registered
i2c i2c-6: i2c-powermac: modalias failure on /u3@0,f8000000/i2c@f8001000/cereal@1c0
PowerMac i2c bus u3 0 registered

The deq node has no compatible, perhaps the modalias can be constructed
out of the name instead?

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2012-06-09 23:10:27

On Sun, 2012-06-10 at 00:59 +0200, Andreas Schwab wrote:
It's a PowerMac G5.  During booting I see this:
There's about half a dozen versions of those :-) I assume the older
PowerMac7,2 ? It's the one that tends to have missing bits in the
device-tree. In that case, I think we still have one of these working at
work, I can have a look when I'm back.
PowerMac i2c bus pmu 2 registered
PowerMac i2c bus pmu 1 registered
PowerMac i2c bus mac-io 0 registered
i2c i2c-5: i2c-powermac: modalias failure
on /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a
i2c i2c-5: i2c-powermac: invalid reg
on /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/i2c-modem
PowerMac i2c bus u3 1 registered
i2c i2c-6: i2c-powermac: modalias failure
on /u3@0,f8000000/i2c@f8001000/cereal@1c0
PowerMac i2c bus u3 0 registered

The deq node has no compatible, perhaps the modalias can be
constructed out of the name instead?
But where is the deq node ? Under i2c or under sound ? If not under i2c
then we need to do something else entirely.

For modalias I'm thinking best might be to have the platform code create
a platform device for sound and have aoa core match on that ;-)

Cheers,
Ben.

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Andreas Schwab <hidden>
Date: 2012-06-10 07:13:31

Benjamin Herrenschmidt [off-list ref] writes:
On Sun, 2012-06-10 at 00:59 +0200, Andreas Schwab wrote:
quoted
It's a PowerMac G5.  During booting I see this:
There's about half a dozen versions of those :-) I assume the older
PowerMac7,2 ?
Yes, that's right.  Sorry for being imprecise.
quoted
PowerMac i2c bus pmu 2 registered
PowerMac i2c bus pmu 1 registered
PowerMac i2c bus mac-io 0 registered
i2c i2c-5: i2c-powermac: modalias failure
on /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a
i2c i2c-5: i2c-powermac: invalid reg
on /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/i2c-modem
PowerMac i2c bus u3 1 registered
i2c i2c-6: i2c-powermac: modalias failure
on /u3@0,f8000000/i2c@f8001000/cereal@1c0
PowerMac i2c bus u3 0 registered

The deq node has no compatible, perhaps the modalias can be
constructed out of the name instead?
But where is the deq node ? Under i2c or under sound ?
It looks like /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a is under
i2c.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2012-06-10 07:23:09

On Sun, 2012-06-10 at 09:13 +0200, Andreas Schwab wrote:
Benjamin Herrenschmidt [off-list ref] writes:
quoted
On Sun, 2012-06-10 at 00:59 +0200, Andreas Schwab wrote:
quoted
It's a PowerMac G5.  During booting I see this:
There's about half a dozen versions of those :-) I assume the older
PowerMac7,2 ?
Yes, that's right.  Sorry for being imprecise.
quoted
quoted
PowerMac i2c bus pmu 2 registered
PowerMac i2c bus pmu 1 registered
PowerMac i2c bus mac-io 0 registered
i2c i2c-5: i2c-powermac: modalias failure
on /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a
i2c i2c-5: i2c-powermac: invalid reg
on /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/i2c-modem
PowerMac i2c bus u3 1 registered
i2c i2c-6: i2c-powermac: modalias failure
on /u3@0,f8000000/i2c@f8001000/cereal@1c0
PowerMac i2c bus u3 0 registered

The deq node has no compatible, perhaps the modalias can be
constructed out of the name instead?
But where is the deq node ? Under i2c or under sound ?
It looks like /ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a is under
i2c.
Ah, excellent, so a small quirk in i2c_powermac is the way to go then,
we can detect it by name and hack up something. Either that or even
better, in prom_init, we could add the missing property to the
device-tree.

Any chance you can try that ? (Look at other examples of DT fixups in
prom_init.c and don't forget the RELOC() around strings :-)

Cheers,
Ben.

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Andreas Schwab <hidden>
Date: 2012-06-10 11:35:54

Benjamin Herrenschmidt [off-list ref] writes:
Ah, excellent, so a small quirk in i2c_powermac is the way to go then,
we can detect it by name and hack up something. Either that or even
better, in prom_init, we could add the missing property to the
device-tree.
How does that look like?  Though I'm not sure this is the right
approach.  Those models with the onyx chip that lack the pcm3052
compatible property apparently have no OF node at all to key off the
workaround.

Andreas.
diff --git i/arch/powerpc/kernel/prom_init.c w/arch/powerpc/kernel/prom_init.c
index 1b488e5..1b04159 100644
--- i/arch/powerpc/kernel/prom_init.c
+++ w/arch/powerpc/kernel/prom_init.c
@@ -2554,7 +2554,7 @@ static void __init fixup_device_tree_chrp(void)
 #endif
 
 #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
-static void __init fixup_device_tree_pmac(void)
+static void __init fixup_device_tree_pmac_u3_i2c(void)
 {
 	phandle u3, i2c, mpic;
 	u32 u3_rev;
@@ -2593,6 +2593,39 @@ static void __init fixup_device_tree_pmac(void)
 	prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
 		     &parent, sizeof(parent));
 }
+
+static void __init fixup_device_tree_pmac_deq(void)
+{
+	phandle deq;
+	u32 i2c_address;
+
+	/*
+	 * On older G5s the tas3004 is described by a deq node missing a
+	 * compatible definition, instead of a codec node with a
+	 * tas3004,code compatible property. Fix that up here.
+	 */
+	deq = call_prom("finddevice", 1, 1, ADDR("/ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a"));
+	if (!PHANDLE_VALID(deq))
+		return;
+	/* Check for proper i2c-address. */
+	if (prom_getprop(deq, "i2c-address", &i2c_address, sizeof(i2c_address)) == PROM_ERROR)
+		return;
+	i2c_address = (i2c_address >> 1) & 0x7f;
+	if (i2c_address != 0x34 && i2c_address != 0x35)
+		return;
+
+	prom_printf("fixing up missing compatible for deq node...\n");
+
+	prom_setprop (deq, "/ht@0,f2000000/pci@1/mac-io@7/i2c@18000/deq@6a",
+		      "compatible", &RELOC("tas3004\0codec\0"),
+		      sizeof("tas3004\0codec\0"));
+}
+
+static void __init fixup_device_tree_pmac(void)
+{
+	fixup_device_tree_pmac_u3_i2c();
+	fixup_device_tree_pmac_deq();
+}
 #else
 #define fixup_device_tree_pmac()
 #endif
-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2012-06-18 01:27:30

On Sun, 2012-06-10 at 17:23 +1000, Benjamin Herrenschmidt wrote:
Ah, excellent, so a small quirk in i2c_powermac is the way to go then,
we can detect it by name and hack up something. Either that or even
better, in prom_init, we could add the missing property to the
device-tree.

Any chance you can try that ? (Look at other examples of DT fixups in
prom_init.c and don't forget the RELOC() around strings :-)
Ok, don't bother. I've been looking into it more closely and I think
the best solution here is actually self contained in i2c-powermac.

I found a couple more device-tree oddities in older machines that
I'm adding workarounds for as well. I'll send a couple of patches
later today including your original one.

Cheers,
Ben.

Re: [PATCH 01/15] i2c/powermac: Register i2c devices from device-tree

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2012-06-18 02:03:16

On Sat, 2012-06-09 at 15:58 +0200, Andreas Schwab wrote:
That breaks the tas3004 driver (and most likely the pcm3052 driver as
well), since it wants to create its own i2c device.  I'm using the
attached patch as a workaround (only tas3004 driver tested on iBook G4),
but that needs to move the workarounds for the older systems that don't
have proper compatible properties somewhere else, which I don't know
where.

Andreas.
Can I put your signed-off-by: on that one ?

Cheers,
Ben.
quoted hunk
---
 sound/aoa/codecs/onyx.c |   75 ++------------------------------------------
 sound/aoa/codecs/tas.c  |   80 ++---------------------------------------------
 2 files changed, 6 insertions(+), 149 deletions(-)
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 270790d..4cedc69 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -997,45 +997,10 @@ static void onyx_exit_codec(struct aoa_codec *codec)
 	onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
 }
 
-static int onyx_create(struct i2c_adapter *adapter,
-		       struct device_node *node,
-		       int addr)
-{
-	struct i2c_board_info info;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, "aoa_codec_onyx", I2C_NAME_SIZE);
-	info.addr = addr;
-	info.platform_data = node;
-	client = i2c_new_device(adapter, &info);
-	if (!client)
-		return -ENODEV;
-
-	/*
-	 * We know the driver is already loaded, so the device should be
-	 * already bound. If not it means binding failed, which suggests
-	 * the device doesn't really exist and should be deleted.
-	 * Ideally this would be replaced by better checks _before_
-	 * instantiating the device.
-	 */
-	if (!client->driver) {
-		i2c_unregister_device(client);
-		return -ENODEV;
-	}
-
-	/*
-	 * Let i2c-core delete that device on driver removal.
-	 * This is safe because i2c-core holds the core_lock mutex for us.
-	 */
-	list_add_tail(&client->detected, &client->driver->clients);
-	return 0;
-}
-
 static int onyx_i2c_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-	struct device_node *node = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct onyx *onyx;
 	u8 dummy;
 
@@ -1071,40 +1036,6 @@ static int onyx_i2c_probe(struct i2c_client *client,
 	return -ENODEV;
 }
 
-static int onyx_i2c_attach(struct i2c_adapter *adapter)
-{
-	struct device_node *busnode, *dev = NULL;
-	struct pmac_i2c_bus *bus;
-
-	bus = pmac_i2c_adapter_to_bus(adapter);
-	if (bus == NULL)
-		return -ENODEV;
-	busnode = pmac_i2c_get_bus_node(bus);
-
-	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
-		if (of_device_is_compatible(dev, "pcm3052")) {
-			const u32 *addr;
-			printk(KERN_DEBUG PFX "found pcm3052\n");
-			addr = of_get_property(dev, "reg", NULL);
-			if (!addr)
-				return -ENODEV;
-			return onyx_create(adapter, dev, (*addr)>>1);
-		}
-	}
-
-	/* if that didn't work, try desperate mode for older
-	 * machines that have stuff missing from the device tree */
-
-	if (!of_device_is_compatible(busnode, "k2-i2c"))
-		return -ENODEV;
-
-	printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
-	/* probe both possible addresses for the onyx chip */
-	if (onyx_create(adapter, NULL, 0x46) == 0)
-		return 0;
-	return onyx_create(adapter, NULL, 0x47);
-}
-
 static int onyx_i2c_remove(struct i2c_client *client)
 {
 	struct onyx *onyx = i2c_get_clientdata(client);
@@ -1117,16 +1048,16 @@ static int onyx_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id onyx_i2c_id[] = {
-	{ "aoa_codec_onyx", 0 },
+	{ "MAC,pcm3052", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
 
 static struct i2c_driver onyx_driver = {
 	.driver = {
 		.name = "aoa_codec_onyx",
 		.owner = THIS_MODULE,
 	},
-	.attach_adapter = onyx_i2c_attach,
 	.probe = onyx_i2c_probe,
 	.remove = onyx_i2c_remove,
 	.id_table = onyx_i2c_id,
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 8e63d1f..c491ae0 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -883,43 +883,10 @@ static void tas_exit_codec(struct aoa_codec *codec)
 }
 

-static int tas_create(struct i2c_adapter *adapter,
-		       struct device_node *node,
-		       int addr)
-{
-	struct i2c_board_info info;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE);
-	info.addr = addr;
-	info.platform_data = node;
-
-	client = i2c_new_device(adapter, &info);
-	if (!client)
-		return -ENODEV;
-	/*
-	 * We know the driver is already loaded, so the device should be
-	 * already bound. If not it means binding failed, and then there
-	 * is no point in keeping the device instantiated.
-	 */
-	if (!client->driver) {
-		i2c_unregister_device(client);
-		return -ENODEV;
-	}
-
-	/*
-	 * Let i2c-core delete that device on driver removal.
-	 * This is safe because i2c-core holds the core_lock mutex for us.
-	 */
-	list_add_tail(&client->detected, &client->driver->clients);
-	return 0;
-}
-
 static int tas_i2c_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
-	struct device_node *node = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct tas *tas;
 
 	tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
@@ -953,47 +920,6 @@ static int tas_i2c_probe(struct i2c_client *client,
 	return -EINVAL;
 }
 
-static int tas_i2c_attach(struct i2c_adapter *adapter)
-{
-	struct device_node *busnode, *dev = NULL;
-	struct pmac_i2c_bus *bus;
-
-	bus = pmac_i2c_adapter_to_bus(adapter);
-	if (bus == NULL)
-		return -ENODEV;
-	busnode = pmac_i2c_get_bus_node(bus);
-
-	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
-		if (of_device_is_compatible(dev, "tas3004")) {
-			const u32 *addr;
-			printk(KERN_DEBUG PFX "found tas3004\n");
-			addr = of_get_property(dev, "reg", NULL);
-			if (!addr)
-				continue;
-			return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
-		}
-		/* older machines have no 'codec' node with a 'compatible'
-		 * property that says 'tas3004', they just have a 'deq'
-		 * node without any such property... */
-		if (strcmp(dev->name, "deq") == 0) {
-			const u32 *_addr;
-			u32 addr;
-			printk(KERN_DEBUG PFX "found 'deq' node\n");
-			_addr = of_get_property(dev, "i2c-address", NULL);
-			if (!_addr)
-				continue;
-			addr = ((*_addr) >> 1) & 0x7f;
-			/* now, if the address doesn't match any of the two
-			 * that a tas3004 can have, we cannot handle this.
-			 * I doubt it ever happens but hey. */
-			if (addr != 0x34 && addr != 0x35)
-				continue;
-			return tas_create(adapter, dev, addr);
-		}
-	}
-	return -ENODEV;
-}
-
 static int tas_i2c_remove(struct i2c_client *client)
 {
 	struct tas *tas = i2c_get_clientdata(client);
@@ -1011,16 +937,16 @@ static int tas_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tas_i2c_id[] = {
-	{ "aoa_codec_tas", 0 },
+	{ "MAC,tas3004", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c,tas_i2c_id);
 
 static struct i2c_driver tas_driver = {
 	.driver = {
 		.name = "aoa_codec_tas",
 		.owner = THIS_MODULE,
 	},
-	.attach_adapter = tas_i2c_attach,
 	.probe = tas_i2c_probe,
 	.remove = tas_i2c_remove,
 	.id_table = tas_i2c_id,
-- 
1.7.10.4

[PATCH] sound/aoa: remove i2c attach_adapter method

From: Andreas Schwab <hidden>
Date: 2012-06-18 07:30:17

Since i2c-powermac now creates all i2c devices on its own, remove the
attach_adapter methods from the TAS and Onyx drivers, and adjust the
module aliases to match the names used by i2c-powermac.

Signed-off-by: Andreas Schwab <redacted>
---
 sound/aoa/codecs/onyx.c | 75 ++--------------------------------------------
 sound/aoa/codecs/tas.c  | 80 ++-----------------------------------------------
 2 files changed, 6 insertions(+), 149 deletions(-)
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 270790d..4cedc69 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -997,45 +997,10 @@ static void onyx_exit_codec(struct aoa_codec *codec)
 	onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
 }
 
-static int onyx_create(struct i2c_adapter *adapter,
-		       struct device_node *node,
-		       int addr)
-{
-	struct i2c_board_info info;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, "aoa_codec_onyx", I2C_NAME_SIZE);
-	info.addr = addr;
-	info.platform_data = node;
-	client = i2c_new_device(adapter, &info);
-	if (!client)
-		return -ENODEV;
-
-	/*
-	 * We know the driver is already loaded, so the device should be
-	 * already bound. If not it means binding failed, which suggests
-	 * the device doesn't really exist and should be deleted.
-	 * Ideally this would be replaced by better checks _before_
-	 * instantiating the device.
-	 */
-	if (!client->driver) {
-		i2c_unregister_device(client);
-		return -ENODEV;
-	}
-
-	/*
-	 * Let i2c-core delete that device on driver removal.
-	 * This is safe because i2c-core holds the core_lock mutex for us.
-	 */
-	list_add_tail(&client->detected, &client->driver->clients);
-	return 0;
-}
-
 static int onyx_i2c_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-	struct device_node *node = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct onyx *onyx;
 	u8 dummy;
 
@@ -1071,40 +1036,6 @@ static int onyx_i2c_probe(struct i2c_client *client,
 	return -ENODEV;
 }
 
-static int onyx_i2c_attach(struct i2c_adapter *adapter)
-{
-	struct device_node *busnode, *dev = NULL;
-	struct pmac_i2c_bus *bus;
-
-	bus = pmac_i2c_adapter_to_bus(adapter);
-	if (bus == NULL)
-		return -ENODEV;
-	busnode = pmac_i2c_get_bus_node(bus);
-
-	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
-		if (of_device_is_compatible(dev, "pcm3052")) {
-			const u32 *addr;
-			printk(KERN_DEBUG PFX "found pcm3052\n");
-			addr = of_get_property(dev, "reg", NULL);
-			if (!addr)
-				return -ENODEV;
-			return onyx_create(adapter, dev, (*addr)>>1);
-		}
-	}
-
-	/* if that didn't work, try desperate mode for older
-	 * machines that have stuff missing from the device tree */
-
-	if (!of_device_is_compatible(busnode, "k2-i2c"))
-		return -ENODEV;
-
-	printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
-	/* probe both possible addresses for the onyx chip */
-	if (onyx_create(adapter, NULL, 0x46) == 0)
-		return 0;
-	return onyx_create(adapter, NULL, 0x47);
-}
-
 static int onyx_i2c_remove(struct i2c_client *client)
 {
 	struct onyx *onyx = i2c_get_clientdata(client);
@@ -1117,16 +1048,16 @@ static int onyx_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id onyx_i2c_id[] = {
-	{ "aoa_codec_onyx", 0 },
+	{ "MAC,pcm3052", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
 
 static struct i2c_driver onyx_driver = {
 	.driver = {
 		.name = "aoa_codec_onyx",
 		.owner = THIS_MODULE,
 	},
-	.attach_adapter = onyx_i2c_attach,
 	.probe = onyx_i2c_probe,
 	.remove = onyx_i2c_remove,
 	.id_table = onyx_i2c_id,
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 8e63d1f..c491ae0 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -883,43 +883,10 @@ static void tas_exit_codec(struct aoa_codec *codec)
 }
 
 
-static int tas_create(struct i2c_adapter *adapter,
-		       struct device_node *node,
-		       int addr)
-{
-	struct i2c_board_info info;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE);
-	info.addr = addr;
-	info.platform_data = node;
-
-	client = i2c_new_device(adapter, &info);
-	if (!client)
-		return -ENODEV;
-	/*
-	 * We know the driver is already loaded, so the device should be
-	 * already bound. If not it means binding failed, and then there
-	 * is no point in keeping the device instantiated.
-	 */
-	if (!client->driver) {
-		i2c_unregister_device(client);
-		return -ENODEV;
-	}
-
-	/*
-	 * Let i2c-core delete that device on driver removal.
-	 * This is safe because i2c-core holds the core_lock mutex for us.
-	 */
-	list_add_tail(&client->detected, &client->driver->clients);
-	return 0;
-}
-
 static int tas_i2c_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
-	struct device_node *node = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
 	struct tas *tas;
 
 	tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
@@ -953,47 +920,6 @@ static int tas_i2c_probe(struct i2c_client *client,
 	return -EINVAL;
 }
 
-static int tas_i2c_attach(struct i2c_adapter *adapter)
-{
-	struct device_node *busnode, *dev = NULL;
-	struct pmac_i2c_bus *bus;
-
-	bus = pmac_i2c_adapter_to_bus(adapter);
-	if (bus == NULL)
-		return -ENODEV;
-	busnode = pmac_i2c_get_bus_node(bus);
-
-	while ((dev = of_get_next_child(busnode, dev)) != NULL) {
-		if (of_device_is_compatible(dev, "tas3004")) {
-			const u32 *addr;
-			printk(KERN_DEBUG PFX "found tas3004\n");
-			addr = of_get_property(dev, "reg", NULL);
-			if (!addr)
-				continue;
-			return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
-		}
-		/* older machines have no 'codec' node with a 'compatible'
-		 * property that says 'tas3004', they just have a 'deq'
-		 * node without any such property... */
-		if (strcmp(dev->name, "deq") == 0) {
-			const u32 *_addr;
-			u32 addr;
-			printk(KERN_DEBUG PFX "found 'deq' node\n");
-			_addr = of_get_property(dev, "i2c-address", NULL);
-			if (!_addr)
-				continue;
-			addr = ((*_addr) >> 1) & 0x7f;
-			/* now, if the address doesn't match any of the two
-			 * that a tas3004 can have, we cannot handle this.
-			 * I doubt it ever happens but hey. */
-			if (addr != 0x34 && addr != 0x35)
-				continue;
-			return tas_create(adapter, dev, addr);
-		}
-	}
-	return -ENODEV;
-}
-
 static int tas_i2c_remove(struct i2c_client *client)
 {
 	struct tas *tas = i2c_get_clientdata(client);
@@ -1011,16 +937,16 @@ static int tas_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tas_i2c_id[] = {
-	{ "aoa_codec_tas", 0 },
+	{ "MAC,tas3004", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c,tas_i2c_id);
 
 static struct i2c_driver tas_driver = {
 	.driver = {
 		.name = "aoa_codec_tas",
 		.owner = THIS_MODULE,
 	},
-	.attach_adapter = tas_i2c_attach,
 	.probe = tas_i2c_probe,
 	.remove = tas_i2c_remove,
 	.id_table = tas_i2c_id,
-- 
1.7.11


Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help